android - 使用 backstack 时 fragment 未替换

标签 android android-fragments navigation back-stack

我有一个使用抽屉导航的应用程序。抽屉可让您在 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 ,而是出现在上面,就像我添加了它一样: F2 not replacing 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/

相关文章:

android - 如何使向上按钮返回而不是打开抽屉导航

android - Retrofit 2 有两条动态路径

android - 可调整的自定义用户界面

android - fragment 的布局字段在初始化时为 NULL

jquery - Superfish下拉位置

css - 子菜单打开时保持导航列表项处于选中状态

android - 如何修复 Android SQLITE_ERROR,错误代码 1

android-如何防止输入键/点击来自条形码扫描仪

机器人 : open chrome custom tab from fragment

Android - 在我的应用程序首选项中实现 ListPreferences