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 FragmentManager
this 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 BadParcelableException
from 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 Fragments
with 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
, only Fragments
added to the Activity
’s 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 onCreate()
.
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.