简体   繁体   中英

Initial Fragment not rendered when popping entire FragmentManager BackStack

Actual problem / TL;DR: Except when using one way I consider a hack, I can't pop the activity's entire backstack to return to my initial state with a single fragment added during onCreate(). The Fragment is present in the Activity State Manager dump, but is not visible, leaving me with an empty screen.

I have encountered this issue today and am mostly trying to understand whether this is caused by a bug or by my misunderstanding of the FragmentManager's BackStack. I want to make sure I'm not misusing Fragments or building on shaky API foundations.

I have an activity which essentially offers a descending "tree" navigation as a grid of buttons where each button opens either a sub-grid (eg sub-category with more buttons) or some custom form. The content of the forms is irrelevant, but users are expected to repetitively fill them in various orders.

I use Fragments from the support library (support-v4:25.1.1) and whenever a new "screen" is required (either for a form or a sub-grid) it will be added using a transaction on the activity's FragmentManager similar to:

/* adding a new screen, going further down our nav tree */
fragmentManager
            .beginTransaction()
            .addToBackStack("...")
            .replace(R.id.container, newFragment)
            .commit();

Every transaction looks like that except the setup of the initial state of my activity, which adds the initial "root grid" fragment without adding the transaction to the backstate.

/* adding the initial fragment during the first execution of activity's onCreate(). */
fragmentManager
            .beginTransaction()
            .replace(R.id.container, rootFragment)
            .commit();

The reason I'm posting here is that I encountered a very strange behaviour when attempting to pop the entire BackStack, which is supposed to bring the user back to the initial state of the activity which has the root grid (the one added in the code above). Almost every technique I tried effectively clears the backstack, but leaves an empty screen instead of my initial main-menu grid. After looking around on multiple questions here and the docs, I tried multiple solutions and only this hack-looking one has worked:

int remainingEntries = fragmentManager.getBackStackEntryCount();
while (remainingEntries-- > 0) {
    fragmentManager.popBackStackImmediate();
}

I say this seems like a hack because it requires me to immediately (synchronously) pop an arbitrary number of backstack entries to reach the root, whereas from my understanding it should be possible to do that with a single asynchronous method call:

fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

or as I've also seen posted around here:

int id = fragmentManager.getBackStackEntryAt(0).getId();
fragmentManager.popBackStack(id, FragmentManager.POP_BACK_STACK_INCLUSIVE);

This is only an issue with the root fragment, probably because the transaction which adds it to the view is not added to the backstack, since that would cause an extra empty screen to be shown when the user presses the back button to close the activity.

More details:

  • According to the Activity State Manager dump my fragment still has its view, but has both mFragmentId and mContainerId set to #0.
  • I do add another fragment I haven't discussed here which retains its instance, but it is only used to hold some data and has no view whatsoever.

There is a PopBackStackImmediate bug in support library version 25.1.0 and above. Since this issue has been reported either you have to wait for solution, Or you can downgrade the support library version to 25.0.1 and get the expected behavior.

UPDATE

Looks like this bug has been resolved in support library version 25.3.1 . Update your library to version 25.3.1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM