为什么Fragmenttransaction replace()像add()一样起作用?

时间:2019-05-16 17:55:14

标签: android android-fragments kotlin android-fragmentactivity fragmentmanager

我有here a sample GitHub project。通过点击底部选项卡,这只是一种夸大其他片段的活动:

  1. 启动将片段1夸大
  2. 按1.Tab->使片段1膨胀
  3. 按下2.Tab->使片段2膨胀
  4. 按下3.Tab->使片段3膨胀

,并且全部通过this.supportFragmentManager?.beginTransaction()?.replace()使用。对我来说,它就像FragmentTransaction.add(),因为:

当我启动应用程序(已加载片段1)并按

  • 片段2(吐司片段2)的第二个标签
  • 和片段3(吐司片段3)的第三个标签
  • 然后返回按钮(Toast Frag 2)
  • 再次返回按钮(Toast Frag 1)

所有堆栈都在工作。所以什么都没有“ 替换”,什么都添加了

每当我按回时,我都会加载“片段1”,这是该活动的初始片段。怎么样?

1 个答案:

答案 0 :(得分:0)

我想这是因为片段被替换了,但它们也被添加到BackStack中,如下所示:

BaseActivity.kt

// Note the .addToBackStack(null)
this.supportFragmentManager?.beginTransaction()?.replace(resId, newFragment)?.addToBackStack(null)?.commit()

From Documentation for addToBackStack

  

将此事务添加到后台堆栈。这意味着该事务在提交后将被记住,并且在以后从堆栈中弹出时将撤消其操作。

您可能希望check this question检查有关addreplaceaddToBackStack之间差异的更多信息。

如果您不想“记住并恢复”片段过渡,只需删除对addToBackStack的调用即可。

修改

如果您始终想返回第一个片段,可以执行以下操作:

保留addToBackStack()。因此,导航历史记录将被保留

this.supportFragmentManager?.beginTransaction()?.replace(resId, 

newFragment)?. addToBackStack(null)?. commit()

onBackPressedMainActivity上覆盖BaseActivity并请求始终返回到第一次事务提交:

override fun onBackPressed() {
    if(this.supportFragmentManager?.getBackStackEntryCount() > 0) {
        this.supportFragmentManager?.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
    } else {
       super.onBackPressed()
    }
}

请注意,这是测试代码,我无法验证。另外,我对Kotlin不熟悉。因此,这是我可以附带的最好的代码...测试并让我知道结果...无论如何,您都可以得到想法。

另一个选择:

删除addToBackStack()

this.supportFragmentManager?.beginTransaction()?.replace(resId, newFragment)?.addToBackStack(null)?.commit()

然后,您必须手动控制当用户按下返回键时应显示哪个片段...类似

private var int : mCurrentFragment = 1

private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
    when (item.itemId) {
        R.id.navigation_home -> {
            mCurrentFragment = 1
            ...
        }
        R.id.navigation_dashboard -> {
            mCurrentFragment = 2
            ...
        }
        R.id.navigation_notifications -> {
            mCurrentFragment = 3
            ...
        }
    }
    false
}

override fun onBackPressed() {
    if(mCurrentFragment != 1) {
        replaceFragment(R.id.container_main_layout, Fragment1())
    } else {
       super.onBackPressed()
    }
}
相关问题