7

目前我有一个活动,并且正在向其中添加片段(搜索、歌曲详细信息、设置等)。我实现了基于侧面的菜单导航,所以现在,作为一个副作用,有多少 Fragment 被添加到 Backstack 中是没有限制的。有什么办法可以限制片段的数量,或者删除旧条目? 例如,每个歌曲详情片段都有一个推荐歌曲列表,通过它您可以转到另一个歌曲详情片段。在 backstack 中很容易有 30 个片段,如果您打开 DDMS,您可以看到堆大小缓慢(但肯定)增加。

编辑:我确实尝试做的一件事是,如果用户单击了一个侧面菜单选项,如果该片段已经在后台堆栈中,则尝试返回该片段而不是实例化一个新片段,但是当然,如​​果用户是在歌曲详细信息页面上,然后他会期望按下返回会将他带到该片段,这样就行不通了。

编辑 2:这是我的 addFragment 方法(连同菲尔的建议):

public void addFragment(Fragment fragment) { 

        FragmentManager fm = getSupportFragmentManager();
        if(fm.getBackStackEntryCount() > 2) {

              fm.popBackStack();
            }
        fm.beginTransaction()                 
                  .replace(R.id.fragment_container, fragment).addToBackStack("")
                  .commit();
}

我刚刚尝试过,假设我的 Fragment 历史是:A->B->C->D,从 D 返回,进入 B->A->exit。

我只是深入了8个级别来测试:A->B->C->D->E->F->G->H,然后从H返回,同样的事情发生了:H->B->A- >退出。

所有片段都是通过上面的方法添加的。我想看到的是:H->G->F->exit。

4

2 回答 2

12

您可以通过编程方式控制 BackStack 中的 Fragment 数量:

FragmentManager fm = getActivity().getSupportFragmentManager();

if(fm.getBackStackEntryCount() > 10) {

   fm.popBackStack(); // remove one (you can also remove more)
}

只需检查您的 Backstack 中有多少 Fragment,如果有“溢出”则删除。

如果要从 BackStack 中删除特定的 Fragment,则必须实现自己的 BackStack并覆盖 onBackPressed()。由于 Fragment BackStack 是一个 Stack(顾名思义),只能移除顶部元素(最后添加的),不可能移除中间的 Fragment。

例如,您可以使用

ArrayList<Fragment>

实现自己的堆栈。只需在需要时从该“堆栈”(它不再是真正的堆栈)中添加和删除片段,并通过覆盖 onBackPressed() 方法来处理先前片段的加载。

于 2013-08-17T21:47:39.923 回答
3

这是一个老问题,但我的回答可能会对某人有所帮助。

为什么不检查片段是否在堆栈中并弹出它?这样您就不必担心返回堆栈的大小(除非您有很多片段)。

    String backStateName = fragment.getClass().getName();
    boolean fragmentPopped = false;
    try {
        // true if fragment is in the stack
        fragmentPopped = fragmentManager.popBackStackImmediate(backStateName, 0);
    } catch (Exception e) {
        e.printStackTrace();
    }

    FragmentTransaction ft = fragmentManager.beginTransaction();

    if ( !fragmentPopped ) { //fragment not in back stack, add it...            
        ft.setTransition( FragmentTransaction.TRANSIT_FRAGMENT_FADE );
        ft.replace(R.id.main, fragment);
        ft.addToBackStack( backStateName );

        try {
            ft.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }           
    }
于 2014-08-23T12:38:00.803 回答