【问题标题】:Android - limit number of fragments in backStack?Android - 限制 backStack 中的片段数量?
【发布时间】:2013-08-20 01:19:24
【问题描述】:

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

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

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

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。

【问题讨论】:

    标签: android android-fragments android-activity back-button


    【解决方案1】:

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

    FragmentManager fm = getActivity().getSupportFragmentManager();
    
    if(fm.getBackStackEntryCount() > 10) {
    
       fm.popBackStack(); // remove one (you can also remove more)
    }
    

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

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

    例如,您可以使用

    ArrayList<Fragment>
    

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

    【讨论】:

    • myFrag 来自哪里?假设我在即将添加新 Fragment 时运行此代码,我是否已经必须引用所有以前的 Fragment?
    • 这只是一个示例代码,例如 myFrag 可以是当前活动的 Fragment。此代码也适用于在 if 语句中调用 fm.popBackStack()。
    • 您似乎走在正确的轨道上,但我希望删除最旧的片段。请参阅编辑以获取说明。到目前为止,我非常感谢您的帮助。
    • 查看我编辑的答案,我很确定没有办法从 BackStack 中删除特定的片段。但是,实现自己的“堆栈”应该很容易。
    【解决方案2】:

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

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

        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();
            }           
        }
    

    【讨论】:

      猜你喜欢
      • 2012-12-30
      • 2014-09-26
      • 1970-01-01
      • 1970-01-01
      • 2017-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多