问题
Currently I have one activity, and fragments are being added to it (search, song details, settings, etc). I implemented side based menu navigation, so now, as a side effect, tehre's no limit to how many Fragments get added to the Backstack. Is there any way I can limit the number of fragments, or remove older entries? Each song details fragment for instance, has a recommended song list, and through that you can go to another song details fragment. It's easily possible to have 30 fragments in the backstack, which if you have DDMS open, you can see the heap size slowly (but surely) increasing.
Edit: One thing I did try to do is if a User clicked one of the side menu options, if that fragment is already in the backstack try to go back to that fragment instead of instantiating a new one, but of course, if a user is on a Song Details page, then he would expect pressing back would take him to that Fragment so that won't work.
Edit 2: This is my addFragment method (along with Phil's suggestion):
public void addFragment(Fragment fragment) {
FragmentManager fm = getSupportFragmentManager();
if(fm.getBackStackEntryCount() > 2) {
fm.popBackStack();
}
fm.beginTransaction()
.replace(R.id.fragment_container, fragment).addToBackStack("")
.commit();
}
I just tried it, and assuming my Fragment history is: A->B->C->D, going back from D, goes B->A->exit.
I just went 8 levels deep to test: A->B->C->D->E->F->G->H, and going back from H, same thing happened: H->B->A->exit.
All Fragments are getting added through that method above. What I would like to see is: H->G->F->exit.
回答1:
You can programatically control the number of Fragments in your BackStack:
FragmentManager fm = getActivity().getSupportFragmentManager();
if(fm.getBackStackEntryCount() > 10) {
fm.popBackStack(); // remove one (you can also remove more)
}
Simply check how many Fragments there are in your Backstack and remove if there is an "overflow".
If you want to remove specific Fragments from the BackStack, you will have to implement your own BackStack and override onBackPressed(). Since the Fragment BackStack is a Stack (as the name indicates), only the top element (the last added) can be removed, there is no possibility of removing Fragments in between.
You could for example use
ArrayList<Fragment>
to realize your own stack. Simply add and remove Fragments from that "stack" (it's not really a stack anymore) whenever you desire and handle the loading of previous fragments by overriding the onBackPressed() method.
回答2:
This is an old question but my answer might help someone.
Why not checking if the fragment is in the stack and pop it? This way you wouldn't have to worry with back stack size (unless you have a lot of fragments).
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();
}
}
来源:https://stackoverflow.com/questions/18293560/android-limit-number-of-fragments-in-backstack