使用Backstack时片段未被替换

时间:2014-08-15 19:14:19

标签: android android-fragments navigation back-stack

我有一个使用导航抽屉的应用程序。抽屉可让您在两个片段之间导航:F1和F2:

活动布局:

<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中替换片段的代码:

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上我有一个按钮来调用另一个片段(F3)。当F3替换F1时,我可以使用addToBackStack()按返回返回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。
通过后退按钮(后退)按F2到F1 导航抽屉F1到F2

最后一个片段(F2)不会取代F1,而是会显示在上面,就像我添加了它一样: F2 not replacing F1

执行相同的导航但不使用后退按钮按预期工作。

为什么后台堆坏了碎片替换?

我的目标是在F1和F3之间提供后退导航,但不在导航抽屉访问的片段之间。

2 个答案:

答案 0 :(得分:3)

让我们了解每一步发生的事情:

  • 按钮F1到F3。

自调用addToBackStack以来,为此事务创建了一个后栈条目。在后栈表项中记录2个操作:

  

op1:删除F1

     

op2:添加F3

  • 通过导航抽屉F3到F2。

如果导航抽屉没有使用addToBackStack,那么后面堆栈完全不知道此事务中删除了F3并添加了F2。

  • 通过后退按钮(Backstack)F2到F1。

按下后退按钮,最后记录的后退堆栈条目的操作将被反转。最后记录的条目是删除F1&amp;添加F3。预期结果将是:

  

op1:删除F1 =&gt;添加F1

     

op2:添加F3 =&gt;删除F3

由于F3在之前的交易中已被删除,因此没有操作。后栈完全没有意识到F2,因此保持不变。到此交易结束时,F1和F2都会添加到活动窗口中。由于F1尺寸大于F2,因此未见。

  • 导航抽屉的F1到F2

此交易只会将F2置于F1之上,因为两者都已添加到活动窗口中。

解决方案:由于后退导航只能在F1&amp; F3,当用户使用导航抽屉导航到不同的片段时,只需清除后面的堆栈。

FragmentManager fm = getActivity().getFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); i++) {    
    fm.popBackStack();
}

答案 1 :(得分:0)

试试这个

getFragmentManager().beginTransaction()
                .replace(R.id.content_frame, new GameFragment())
                .addToBackStack(null).commit();