所以我有一个包含MapsFragment的活动,首先将其初始化而不将其存储在backstack中(如果我将它存储在backstack中,按下后退按钮弹出片段并留下空容器,这不是我想要的)。这是代码:
transaction.replace(mFragmentContainerRes,
MapsFragment.newInstance(), MapsFragment.getClass().getName()).commit();
然后我将其替换为ChatRoomFragment,如下所示:
transaction.replace(mFragmentContainerRes,
ChatRoomFragment .newInstance(), ChatRoomFragment .getClass().getName())
.addToBackStack(ChatRoomFragment .getClass().getName());
transaction.commit();
然后我在我的主要活动中有一个导航抽屉,当按下主页按钮时,我从backstack中检索这样的MapsFragment:
Fragment fragment = manager.findFragmentByTag(MapFragment.getClass().getName());
transaction.replace(mFragmentContainerRes, fragment, backStateName).commit();
现在,如果我在检索到的MapsFragment中按下后退按钮,应用程序会因抛出此错误而崩溃:
java.lang.IllegalStateException:
Fragment already added: MapsFragment{e34dc65 #0 id=0x7f0f00b4 com.MapsFragment}
at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1882)
at android.support.v4.app.BackStackRecord.executePopOps(BackStackRecord.java:825)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2577)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:851)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:794)
at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:174)
at com.main.MainActivity.onBackPressed(MainActivity.java:111)
出于某种原因,当我按下后退按钮时,Activity正在尝试再次添加MapsFragment。为什么是这样?我该如何解决这个问题?
根据我的研究,如果你.add而不是.replace,这通常会发生,但我在片段交易中到处都是.replace。
答案 0 :(得分:1)
当想要返回到主片段而不是用主片段替换当前片段时,通过弹出我的整个backstack解决了这个问题:
getSupportFragmentManager().popBackStack(null,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
答案 1 :(得分:0)
片段堆栈仅存储FragmentTransactions,而不是实际的片段。当您单击返回时弹出它时,它会简单地逆转此事务。因此,在您的情况下,您将使用replace加载ChatRoomFragment,这与删除所有片段并添加ChatRoomFragment相同。因此前进的FragmentTransaction是[1 - Remove MapsFragment, 2 - Add ChatRoomFragment]
。这是FragmentTransaction,已执行,现在您位于ChatRoomFragment。如果现在popBackStack
,它会像应该的那样工作。事务被撤消,删除ChatRoomFragment并添加MapsFragment。
单击NavDrawer上的“主页”按钮时,将替换MapsFragment,这与删除ChatRoomFragment和添加MapsFragment相同。请注意,该事务未添加到Backstack中,因此当前Backstack仍为[1 - Add MapsFragment, 2 - Remove ChatRoomFragment]
,与上一段中的FragmentTransaction初始相反。愚蠢的堆栈并不知道您替换了MapsFragment,而是当前的片段,因此,当您现在单击“后退”按钮时,它只是执行当前的堆栈,并尝试再次添加MapsFragment并收到该Fragment already added
错误。>
您选择的解决方案之所以有效,是因为当用户单击NavDrawer上的“主页”按钮时,您只是在弹出后退堆栈,而后退堆栈现在已清除。