我正在使用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();
    }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top