如何在安卓中清除Fragment返回栈

55

你好,我该如何清除碎片返回栈?我使用了以下逻辑但并没有生效...

for(int i = 0; i < mFragmentManager.getBackStackEntryCount(); ++i) {            
     mFragmentManager.popBackStack();
}

帮帮我..

6个回答

123

试一试

mFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); 

6
如果您在清空回退栈后立即添加新内容,则可能需要调用popBackStackImmediate而不是popBackStack。请详细说明,因为这是最佳解决方案之一。 - marsbear
14
如果后退栈中有超过一个状态,这将只弹出顶部状态,而不清除后退栈。 - J.G.Sebring
这会在提交新的 Fragment 事务之前加载先前的 Fragment。虽然你看不到,但程序上会在新的 Fragment 前调用先前 Fragment 的 onActivityCreated() 方法。 - VasileM
@VasileM 那我们该如何克服这个问题呢? - Damia Fuentes

82

上面的答案几乎正确,但是你需要在片段后退列表周围加上保护措施,因为它可能为空:

private void clearBackStack() {
    FragmentManager manager = getSupportFragmentManager();
    if (manager.getBackStackEntryCount() > 0) {
        FragmentManager.BackStackEntry first = manager.getBackStackEntryAt(0);
         manager.popBackStack(first.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }
}

这是我迄今为止找到的最好的答案,它承认了实际问题。赞。 - anwarshahriar

20
while (getSupportFragmentManager().getBackStackEntryCount() > 0){
    getSupportFragmentManager().popBackStackImmediate();
}

如果您能更详细地阐述,这应该是被接受的答案。清除整个后退堆栈是我们想要的。 - HaydenKai
2
但它只显示最后一个。通常,在此之后,您只需将新片段添加到返回堆栈即可。 - Draško
这里有一个需要注意的地方,就是在像这样的循环中弹出后退栈将会调用所有被弹出的片段中的生命周期事件(包括创建方法和关闭方法),这可能会导致意外的副作用。 - Teun Kooijman

17

一种方法是对backstack进行标记,当你想要清除它时

mFragmentManager.popBackStack("myfancyname", FragmentManager.POP_BACK_STACK_INCLUSIVE);

其中"myfancyname"应该与您在addToBackStack中使用的字符串匹配。例如:

其中"myfancyname"应该与您在addToBackStack中使用的字符串匹配。例如:

Fragment fancyFragment = new FancyFragment();     
fragmentTransaction.replace(R.id.content_container, fancyFragment, "myfragmentag");
fragmentTransaction.addToBackStack("myfancyname");

回退栈的名称和片段的标记名称可以相同,但在这方面没有任何限制。

来自文档:

如果设置了回退栈条目的名称或 ID,则会消耗所有匹配的条目,直到找到一个不匹配的条目或达到堆栈底部。否则,将删除该条目之前的所有条目,但不包括该条目。

如果您不想为回退栈使用名称,可以传递第一个参数。

 mFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

你如何为后退栈命名? - Gokhan Arik
1
Gokhan,这个名称不是backstack的名称,而是Fragment的标签名称。对于他的示例,他要弹出的Fragment将会像这样添加:mFragmentManager.beginTransaction().add(mFragment, "myfancyname"); - nt-complete

12

可能有点晚了,但我刚刚遇到了这个问题。你可以这样做:

FragmentManager manager = getFragmentManager();
FragmentManager.BackStackEntry first = manager.getBackStackEntryAt(0);
manager.popBackStack(first.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);

非常简单易懂;您只需获取第一条记录,获取其ID,然后弹出包括该ID的记录及其之前的所有内容。


0

我见过的最好选择就在这里。

            int count = getSupportFragmentManager().getBackStackEntryCount();
            if (count > 0) {
                getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接