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 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):

simple-stack setup: lifecycle event callbacks and state changer implementation

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:

Navigator setup

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:

The BackstackHost (retained fragment as lifecycle listener)

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:

View change handlers

And in the end, creating a more complex version of the DefaultStateChanger looks like this:

Navigator configuration with DefaultStateChanger

After that, you can use your custom viewgroups just as you would, any other time.

Backstack operators

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.