我有一个使用抽屉导航的应用程序。抽屉可让您在 2 个 fragment 之间导航:F1 和 F2:
Activity 布局:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"/>
<!-- The navigation drawer -->
<ListView android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:dividerHeight="0dp"
android:background="#f5f5f5"/>
</android.support.v4.widget.DrawerLayout>
替换 Activity 中 fragment 的代码:
private void selectItem(int position) {
Fragment fragment;
fragment = getFragmentToDisplay(position);
if(fragment != null)
{
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment,"fragment_"+position)
.commit();
}
}
在 F1 上,我有一个按钮可以调用其他 fragment (F3)。当 F3 替换 F1 时,我使用 addToBackStack()
可以通过按 return 返回到 F1。
用 F3 替换 F1:
getFragmentManager().beginTransaction()
.replace(R.id.content_frame, new GameFragment())
.addToBackStack("Games").commit();
从 F1 到 F2,F2 到 F1 效果完美。
从 F1 到 F3、F3 到 F1(使用后退按钮)也可以。
尽管如此,如果我正在执行此序列:
通过按钮 F1 到 F3。
通过抽屉导航 F3 到 F2。
通过后退按钮 (backstack) F2 到 F1。
通过抽屉导航 F1 到 F2
最后一个 fragment (F2) 不会替换 F1 ,而是出现在上面,就像我添加了它一样:
执行相同的导航但不使用后退按钮可以按预期工作。
为什么返回堆栈会干扰 fragment 替换?
我的目标是在 F1 和 F3 之间提供后退导航,但不在抽屉导航访问的 fragment 之间提供后退导航。
最佳答案
让我们了解每一步会发生什么:
- 通过按钮按 F1 到 F3。
由于调用了addToBackStack
,因此为此事务创建了一个返回堆栈条目。在返回堆栈条目中记录了 2 个操作:
op1: remove F1
op2: add F3
- 通过抽屉导航按 F3 到 F2。
如果您没有使用抽屉导航 addToBackStack
,则返回堆栈完全不知道删除 F3 并添加 F2 的事务。
- 通过后退按钮 (backstack) 从 F2 切换到 F1。
按下后退按钮时,最后记录的后退堆栈条目的操作将被反转。最后记录的条目是删除 F1 并添加 F3。预期结果是:
op1: remove F1 => add F1
op2: add F3 => remove F3
由于 F3 已在之前的事务中被删除,因此没有任何操作。返回堆栈完全不知道 F2,因此保持原样。在此事务结束时,F1 和 F2 都将添加到 Activity 窗口中。由于F1尺寸比F2大,所以看不到。
- 通过抽屉导航按 F1 到 F2
此事务只会将 F2 置于 F1 之上,因为两者都已添加到 Activity 窗口中。
解决方案:由于后退导航应该只发生在 F1 和 F3 之间,因此当用户使用抽屉导航导航到不同的 fragment 时,只需清除后退堆栈即可。
FragmentManager fm = getActivity().getFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); i++) {
fm.popBackStack();
}
关于android - 使用 backstack 时 fragment 未替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25332744/