我正在使用Android兼容性库来实现片段,并扩展了布局示例,以便片段包含一个触发另一个片段的按钮。
在左侧的选择窗格中,我有5个可选项 - A B C D E
。
每个都会在详情窗格中加载一个片段(通过FragmentTransaction:replace
) - a b c d e
现在我扩展了片段e
以包含一个按钮,该按钮还会在详细信息窗格中加载另一个片段e1
。我在片段e
的onClick方法上做了这个,如下所示:
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.details_frag, newFrag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
如果我做出以下选择:
E - e - e1 - D - E
然后片段e
位于详细信息窗格中。这很好,我想要的。但是,如果我此时按下back
按钮,它什么都不做。我必须单击它两次,因为e1
仍在堆栈中。此外,点击后我在onCreateView中得到了一个空指针异常:
为了“解决”这个问题,每当选择A B C D E
时我都会添加以下内容:
FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
只是想知道这是否是正确的解决方案,还是我应该做些不同的事情?
答案 0 :(得分:246)
根据预期的行为,有几种方法可以解决这个问题,但是此链接应该为您提供所有最佳解决方案,并且不出意外地来自Dianne Hackborn
http://groups.google.com/group/android-developers/browse_thread/thread/d2a5c203dad6ec42
基本上你有以下选择
FragmentManager.popBackStack(String name,
FragmentManager.POP_BACK_STACK_INCLUSIVE)
。FragmentManager.getBackStackEntryCount()
/ getBackStackEntryAt().getId()
检索后栈上第一个条目的ID,和
FragmentManager.popBackStack(int id,
FragmentManager.POP_BACK_STACK_INCLUSIVE)
。FragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
应该弹出整个后台堆栈...我认为文档
那是错的。 (其实我猜它只是不包括在哪里
你传入POP_BACK_STACK_INCLUSIVE
),答案 1 :(得分:60)
如果您不想弹出所有堆栈条目,那么另一个干净的解决方案......
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.home_activity_container, fragmentInstance).addToBackStack(null).commit();
这将首先清理堆栈然后加载一个新的片段,所以在任何给定的点上你只有一个片段在堆栈中
答案 2 :(得分:25)
感谢Joachim回答,我最后使用代码清除所有后台堆栈条目。
// In your FragmentActivity use getSupprotFragmentManager() to get the FragmentManager.
// Clear all back stack.
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
for (int i = 0; i < backStackCount; i++) {
// Get the back stack fragment id.
int backStackId = getSupportFragmentManager().getBackStackEntryAt(i).getId();
fm.popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} /* end of for */
答案 3 :(得分:7)
我已经研究了很多清理Backstack,最后看到Transaction BackStack and its management。这是最适合我的解决方案。
// CLEAR BACK STACK.
private void clearBackStack() {
final FragmentManager fragmentManager = getSupportFragmentManager();
while (fragmentManager.getBackStackEntryCount() != 0) {
fragmentManager.popBackStackImmediate();
}
}
上述方法遍历backstack中的所有事务,并一次一个地删除它们。
注意:以上代码有时无法正常工作,因为此代码,我面临ANR,所以请不要尝试此操作。
<强>更新强> 下面的方法从backstack中删除该“name”的所有fregment。
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack("name",FragmentManager.POP_BACK_STACK_INCLUSIVE);
答案 4 :(得分:3)
我使用的代码与使用while循环的代码类似,但是我在每个循环中调用了条目数...所以我认为它有点慢
FragmentManager manager = getFragmentManager();
while (manager.getBackStackEntryCount() > 0){
manager.popBackStackImmediate();
}
答案 5 :(得分:0)
如How to pop fragment off backstack和@LarsH所述,我们可以使用以下方法从上至下弹出几个片段到特定标签(连同已标记的片段):
for i in listt:
if not i:
continue
if i[0] == 'U':
print "U is:"
print i[1]
用片段的标签替换“ frag”。请记住,首先我们应该使用以下命令将片段添加到后堆栈:
fragmentManager?.popBackStack ("frag", FragmentManager.POP_BACK_STACK_INCLUSIVE);
如果我们使用fragmentTransaction.addToBackStack("frag")
添加片段,则不会以这种方式弹出片段。
答案 6 :(得分:-4)
// pop back stack all the way
final FragmentManager fm = getSherlockActivity().getSupportFragmentManager();
int entryCount = fm.getBackStackEntryCount();
while (entryCount-- > 0) {
fm.popBackStack();
}