fragmentManager.getBackStackEntryCount() does not decrease when removing fragment from manager

Viewed 1143

The correct behavior I'd like to have is:

Fragment A -> Fragment B -> Fragment C -> Fragment A

What I currently do:

  1. When I want to go back from B to A, I use popBackStack() still here everything goes well.
  2. When I want to go from B to C I remove B and add C. (number of Fragments 2, number of backStackEntryCount 3, same for replace).
  3. When I want to go back from C to A, I can use popBackStack() but the BackStackEntryCount will still contain the entry for B.

I really need the backStackEntryCount to be the same as the fragments contained in the manager.

Anyone know what I am doing wrong?

My code:

        Fragment fragment1 = fragmentManager.findFragmentByTag("NavigationFragment_");
    if (fragment1 != null) {
        fragmentManager.beginTransaction()
                .setTransition(TRANSIT_FRAGMENT_FADE)
                .remove(fragment1)
                .commit();

    }

    fragmentManager.beginTransaction()
            .addToBackStack(backstack)
            .setTransition(TRANSIT_FRAGMENT_OPEN)
            //.remove(getFragmentManager().findFragmentByTag(NavigationFragment_.class.getSimpleName()))
            .add(R.id.fragmentContainer, fragment, fragment.getClass().getSimpleName())
            .commit();

I have been searching for a solution for a while without results, so please do not mark this a duplicate.

Thanks in advance.

2 Answers

If you come here because you call popBackStack() but getBackStackEntryCount() doesn't seem to update, then you might want to try popBackStackImmediate() instead.

popBackStack() is asynchronous -- it enqueues the request to pop, but the action will not be performed until the application returns to its event loop.

The FragmentManager's back stack is only updated in two cases:

  1. You commit a FragmentTransaction using addToBackStack()
  2. You call popBackStack()

No other operation affects the back stack - additional FragmentTransactions without addToBackStack() only change the current state and do not affect what happens when you call popBackStack(), etc.

If you want your stack to go from A to A -> B, you'd use a FragmentTransaction with addToBackStack (and generally, a replace operation):

fragmentManager.beginTransaction()
    .replace(R.id.fragmentContainer, fragmentB)
    .addToBackStack("b")
    .commit();

Then, you want your back stack to A -> B to A -> C, you'd need to do two operations:

// First pop B
fragmentManager.popBackStack("b", FragmentManager.POP_BACK_STACK_INCLUSIVE)
// Then addToBackStack C
fragmentManager.beginTransaction()
    .replace(R.id.fragmentContainer, fragmentC)
    .addToBackStack("c")
    .commit();

This ensures that your FragmentB is removed from the stack before adding FragmentC to the back stack.

Similarly, if you want to then remove FragmentC and go back to FragmentA, you'd just pop it from the back stack:

// Pop C, returning back to A
fragmentManager.popBackStack("c", FragmentManager.POP_BACK_STACK_INCLUSIVE)

Note: it is never a good idea to mix back stack FragmentTransactions and regular FragmentTransactions in the same FragmentManager since popBackStack() does not take into account the current state of the FragmentManager, but instead just blindly reverses the FragmentTransaction on the back stack (i.e., the last FragmentTransaction with addToBackStack().

Related