2013-08-17 40 views
6

目前我有一项活动,并且正在添加片段(搜索,歌曲细节,设置等)。我实现了基于侧面的菜单导航,所以现在,作为一个副作用,tehre没有限制将多少碎片添加到Backstack中。 有什么方法可以限制片段数量,或删除较旧的条目?例如,每首歌的细节片段都有一个推荐的歌曲列表,然后通过它可以转到另一首歌曲的细节片段。很容易在后台堆栈中有30个碎片,如果你打开了DDMS,你可以看到堆栈大小缓慢(但肯定)增加。Android - 在backStack中限制片段数量?

编辑:我曾尝试做的一件事是,如果用户单击其中一个侧边菜单选项,如果该片段已经在后台堆叠中,则尝试返回到该片段而不是实例化新片段,但当然,如果用户在Song Details页面上,那么他会希望按回来将他带到该片段,这样就无法工作。

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

我刚刚试了一下,假设我的历史片段是:A-> B-> C-> d,从D开始,从B→A→退出。

我刚刚进入了8级测试:A-> B-> C-> D-> E-> F-> G-> H,并且从H返回,发生同样的事情:H-> B - > A->退出。

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

回答

10

您可以通过编程控制碎片的数量在堆栈中:

FragmentManager fm = getActivity().getSupportFragmentManager(); 

if(fm.getBackStackEntryCount() > 10) { 

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

只需选中多少片段中有你的堆栈中,如果有一个“溢出”删除。

如果你想从堆栈中删除特定片段,你将不得不实现自己的堆栈中并覆盖onBackPressed()。由于Fragment BackStack是一个堆栈(如名称所示),只有顶层元素(最后添加的)可以被删除,所以不可能删除其间的Fragments。

例如,你可以使用

ArrayList<Fragment> 

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

+0

myFrag从哪里来?假设我在添加一个新的Fragment时正在运行这段代码,那么我是否已经必须引用所有以前的Fragments? – StackOverflowed

+0

那么这只是一个示例代码,myFrag可以是例如当前活动的片段。这段代码也可以在if语句中调用fm.popBackStack()。 –

+0

看起来好像你在正确的轨道上,但我想要删除最旧的碎片。请参阅编辑以获得澄清。我非常感谢你的帮助。 – StackOverflowed

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