Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - limit number of fragments in backStack?

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.

like image 914
StackOverflowed Avatar asked Aug 17 '13 21:08

StackOverflowed


2 Answers

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.

like image 158
Philipp Jahoda Avatar answered Nov 05 '22 04:11

Philipp Jahoda


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();
        }           
    }
like image 26
Sidney Veiga Avatar answered Nov 05 '22 05:11

Sidney Veiga