Last November I wrote about the new feature in rev11 of Android support package – Fragments nesting. Recently I had an opportunity to use this feature in practice and I’d like to share my experience with it.
The basics are simple: each
FragmentActivity and each
Fragment has it’s own
FragmentManager. Inside the Fragment you may call
getFragmentManager() to get the
Fragment was added to, or
getChildFragmentManager() to get the
FragmentManager which can be used to nest
Fragments inside this
Fragment. This basic flow works fine, but I have found two issues.
If you have a
Fragment with nested
Fragments and you save its state with
saveFragmentInstanceState() and try to use it in
setInitialSavedState() on another instance of this
Fragment, you’ll get the
onCreate. Fortunately it’s an obvious bug which is easy to fix: you just need to set the correct
ClassLoader for a
Bundle containing this
Fragment’s state. There is a patch for it in support library project Gerrit, and if you need this fix ASAP you may use this fork of support lib on Github.
The second issue is related with the
Fragments backstack. Inside each
FragmentManager you may build stack of
FragmentTransaction.addToBackStack() and later on use
popBackStack() to go back to the previous state. Pressing hardware back key is also supposed to pop the
Fragments from the back stack, but it doesn’t take into account any nested
Fragments added to the
FragmentManager. This is not so easy to fix, but you may use the following workaround:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
Quick explanation: together with the actual backstack entry we want to add, we also add the fake backstack entry with empty
Fragment to top level
FragmentManager and set up
OnBackStackChangedListener. When user presses hardware back button, the fake backstack entry is popped, the backstack listener is triggered and our implementation pops the backstack inside our
Fragment. The backstack listeners are not persisted throughout the orientation change, so we need to setup it again inside
Note that there are two issues with this workaround: it allows adding only one backstack entry and this setup won’t be automatically recreated from state saved by
saveFragmentInstanceState() (fortunately it does work with orientation change). Both issues probably can be solved by some additional hacks, but writing workarounds for workarounds is not something I do unless I really have to, and in this case I neither issue affected me.
Besides those bumps the nested
Fragments are a real blessing which allows much more cleaner and reusable code.