I’ve worked quite a bit on a library named simple-stack, specifically to make it easy to use custom viewgroups as the building blocks of Android applications.
However, the BackstackDelegate
proved to be a bit difficult to work with — delegating numerous lifecycle callbacks just to make it work. Using a retained fragment, this is much easier. Enter Navigator
, a new additional to Simple-Stack 1.5.0.
Navigator
[**Navigator**](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/navigator/Navigator.java)
uses simple-stack
‘s BackstackManager
internally, just like BackstackDelegate
— while also providing some sensible defaults.
Previously, you had to set up simple-stack
like this (with the benefit of working from API 1 and above):
Navigator opts to use the “retained fragment as lifecycle listener” approach employed by both Conductor (MinSDK 16+) and Flow (MinSDK 14+), while also provides a DefaultStateChanger
default implementation, reducing installation to:
I’d say that reduces quite a strain from the library user, right? :)
Instead of relying on manual callbacks and having to persist view state, the retained fragment gets callbacks from the Activity. And as retained fragments survive as long as the activity does, we can even ditch onRetainCustomNonConfigurationInstance()
!
In case you’re curious, this is essentially what the fragment does:
This is all technically code that the library user no longer needs to write. Woo!
Default State Changer
But with Min SDK 11 comes ObjectAnimator
, therefore allowing default animations — therefore making it reasonable to create default state changers and default animators.
If the user chooses to use DefaultStateChanger
, then their state keys must implement an interface called StateKey
. This is what specifies the layout which has the custom viewgroup as the root, and the view change handler that handles the animations.
As you can see, our StateKey
specifies a SegueViewChangeHandler
, which will handle left-right and right-left animation (depending on direction).
But it’s just as easy to provide one for fading over, or even with transitions:
And in the end, creating a more complex version of the DefaultStateChanger
looks like this:
After that, you can use your custom viewgroups just as you would, any other time.
Conclusion
Hopefully you like what you saw in Navigator, (check out the mvp
sample, maybe even the nestedstack
sample), and consider dropping intents and fragment transactions for the sake of simplicity. :)
If not, just the other day I saw a library: Cicerone, that functions as a “command buffer” for navigation operators — exactly what is achieved internally by simple-stack’s detachStateChanger()
and reattachStateChanger()
methods — but as it’s just the command buffer/processor, it can be integrated against any already existing backstack solution — for example, activities and fragments. If custom viewgroups really aren’t your cup of tea, that is worth checking out.
In my opinion, viewgroups are more predictable, so I’m sticking with them. No need to manually destroy and recreate them just to place them into a container with a different ID; this is something that in contrast, fragments could learn from.