这是离开深嵌套堆栈时清理片段后堆栈的正确方法吗?
-
22-10-2019 - |
题
我正在使用Android兼容性库来实现片段,并扩展了布局样本,因此片段包含一个按钮,该按钮可以从另一个片段上启动。
在左侧的选择窗格中,我有5个可选项目 - A B C D E
.
每个加载片段(通过 FragmentTransaction:replace
)在细节窗格中 - a b c d e
现在我扩展了片段 e
包含一个加载另一个片段的按钮 e1
还在细节窗格中。我在片段上做到了 e
如下:
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();
}
只是想知道这是正确的解决方案还是我应该做不同的事情?
解决方案
好吧,有几种方法可以根据预期的行为来解决这一问题,但是此链接应该为您提供所有最好的解决方案,毫不奇怪,来自Dianne Hackborn
http://groups.google.com/group/android-developers/browse_thread/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
),
其他提示
另一个干净的解决方案,如果您不想弹出所有堆栈条目...
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.home_activity_container, fragmentInstance).addToBackStack(null).commit();
这将首先清洁堆栈,然后加载一个新片段,因此在任何给定点,您都只有单个片段
谢谢 约阿希姆 回答,我最终使用代码清除所有背堆条目。
// 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 */
我已经研究了很多用于清洁背景的事情,最后看到 交易背景及其管理. 。这是最适合我的解决方案。
// CLEAR BACK STACK.
private void clearBackStack() {
final FragmentManager fragmentManager = getSupportFragmentManager();
while (fragmentManager.getBackStackEntryCount() != 0) {
fragmentManager.popBackStackImmediate();
}
}
上面的方法循环在背包中的所有交易上,并一次立即将其删除。
笔记: 上面的代码有时不起作用,我会面对 ANR 由于有此代码,因此请不要尝试。
更新下面的方法从背堆中删除该“名称”的所有费用。
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack("name",FragmentManager.POP_BACK_STACK_INCLUSIVE);
- 名称如果非挂钩,这是要寻找的前后状态的名称;如果发现,到该州的所有状态都将被弹出。这
- POP_BACK_STACK_INCLUSIVE FLAG可用于控制命名状态本身是否弹出。如果null,则只有最高状态被弹出。
我使用的代码与使用时循环的代码相似,但我将每个循环中的条目计数称为...所以我想这速度较慢
FragmentManager manager = getFragmentManager();
while (manager.getBackStackEntryCount() > 0){
manager.popBackStackImmediate();
}
// pop back stack all the way
final FragmentManager fm = getSherlockActivity().getSupportFragmentManager();
int entryCount = fm.getBackStackEntryCount();
while (entryCount-- > 0) {
fm.popBackStack();
}