为什么 Fragmenttransaction replace() 就像 add() 一样?

Why Fragmenttransaction replace() acts like a add()?

我有here a sample GitHub project。它只是一个 activity 通过点击底部标签来膨胀其中的其他片段:

  1. Applaunch 使片段 1 膨胀
  2. 按下 1.Tab -> 膨胀片段 1
  3. 按下 2.Tab -> 膨胀片段 2
  4. 按下 3.Tab -> 膨胀片段 3

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

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

所有堆栈都在恢复工作。所以什么都没有“替换”,一切都添加?

每当我返回时,我想加载 "Fragment 1",这是 activity 的初始片段。怎么样?

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

BaseActivity.kt

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

From Documentation for addToBackStack

Add this transaction to the back stack. This means that the transaction will be remembered after it is committed, and will reverse its operation when later popped off the stack.

您可能需要 check this question 查看有关 addreplaceaddToBackStack 之间区别的更多信息。

如果您不想 "remember and restore" 片段转换,只需删除对 addToBackStack.

的调用

编辑

如果你总是想return到第一个片段,你可以这样做:

保留 addToBackStack()。所以,导航历史将被保留

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

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

MainActivityBaseActivity 上覆盖 onBackPressed 并请求总是 return 到第一个事务提交:

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

请注意,这是一个测试代码,我无法验证。另外,我对科特林不熟悉。所以,这是我能得到的最好的代码......测试并让我知道结果......无论如何,你可以得到ideia。

另一个选项:

删除 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()
    }
}