如何用后堆栈中的另一个片段替换多个片段?

时间:2016-11-22 14:09:21

标签: android fragment-backstack fragment-transitions

我在后面的堆栈中有以下片段 A,B,C 。然后我想添加片段 D ,但在后面的堆栈中我想要 A和D 而不是 A,B,C,D 。 问题是,当我尝试使用transaction.remove()删除B和C时,backStackEntryCount仍然是旧的,在按下时会显示空屏幕。有办法解决这个问题吗?

当我使用popBackStack()时,它会转到片段A然后来到D,这会产生奇怪的动画效果。

编辑: 这个问题并没有重复,因为它被标记,因为这个问题更多的是控制后栈中几个片段的顺序。

3 个答案:

答案 0 :(得分:1)

添加到Backstack时,您可以包含一个名称,以便在您处于特定状态时弹出Backstack。基于FragmentManager#popBackStack(string, int);的文档:

  

从管理器的片段回栈中弹出最后一个片段转换。如果没有要弹出的内容,则返回false。此函数是异步的 - 它将请求排入pop,但在应用程序返回其事件循环之前不会执行该操作。

     

<强>参数

     

名称 字符串:如果非空,则这是要查找的上一个后退状态的名称;如果找到,将弹出所有达到该状态的状态。 POP_BACK_STACK_INCLUSIVE标志可用于控制是否弹出命名状态本身。如果为null,则仅弹出顶部状态。

     

标志 int :0或POP_BACK_STACK_INCLUSIVE。

所以在这种情况下你:

将片段A添加到容器和根后台。给它一个名字,这样你就可以在弹出时引用它。

片段A

FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentA, "FragmentA")
.addToBackStack("first")
.commit();

将片段B添加到容器中(替换或添加,无关紧要)。如果您愿意,可以使用“null”或其他名称添加到Backstack。它必须与“第一”不同。

片段B

FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentB, "FragmentB")
.addToBackStack(null)
.commit();

像片段B一样添加或替换片段C。

片段C

FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentC, "FragmentC")
.addToBackStack(null)
.commit();

像片段B和C一样添加或替换片段D。

片段D

FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentD, "FragmentD")
.addToBackStack(null)
.commit();

然后,在onBackPressed()中,首先检查“FragmentD”是否在堆栈中。如果是,则一直弹回到根(在这种情况下是“第一个”)。如果没有,只需像往常一样处理背部按压。

@Override
public void onBackPressed() {
    FragmentManager fm = getFragmentManager();
    if (fm.findFragmentByTag("FragmentD") != null) {
       fm.popBackStack("first", 0); // Pops everything up to "first" 
    } else {
       super.onBackPressed(); // Pops backstack like normal or leaves App if at base.
    }
}

这应该做的是让你的用户在按下片段A,B或C中的后退按钮时“返回”。然后,当他们最终进入片段D时,它会一直弹回到A

答案 1 :(得分:0)

片段A

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, FragmentA, "FragmentA");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();

片段B

fragmentTransaction.replace(R.id.fragment_container, FragmentB, "FragmentB");

片段C

 fragmentTransaction.replace(R.id.fragment_container, FragmentC, "FragmentC");

片段D

 fragmentTransaction.replace(R.id.fragment_container, FragmentD, "FragmentD");

现在你的活动中的onBackPressed()

@Override
public void onBackPressed() {


int lastStack = getSupportFragmentManager().getBackStackEntryCount();
try {
    //If the last fragment was named/tagged "three"
    if (getSupportFragmentManager().getFragments().get(lastStack).getTag().toString()=="FragmentD"){

        getSupportFragmentManager().popBackStackImmediate();//skip c
        getSupportFragmentManager().popBackStackImmediate();//skip B
         Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentA");
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment_container, fragment);
        transaction.commit();
        return;
    }
} catch (Exception e) {

    e.printStackTrace();
}

super.onBackPressed();
 }

答案 2 :(得分:-1)

为每个片段制作fragment_container并继续替换最新片段的fragment_container。 别忘了:

addToBackStack(null);