Modern Android App 🚀

One of the best practices for a modern Android application is to extract your app logic from the standard Android classes (Fragments or Activities) to some special class. For example, if you use MVP pattern, it will be a Presenter. This class contains all presentation logic and tells View implementations what they should show to a user. However, the question arises: How to properly solve the task of navigation between different screens? Probably, the first idea will be to declare such methods in the View: “go to screen X”. However, this is a quite dirty way because the implementation of navigation is not a part of the View’s logic and we violate the Separation of Concerns principle.

Router 💡

A possible solution for this situation is to extract the navigation into a special class — Router. This class should be injected into the screens’ presenters and it gets and somehow executes transition calls. In Android, you can change your active Fragment or Activity only using a Context object, and the Router should delegate the actual transition task to the required Android framework class.

Cicerone 🌠

The idea of Router has been successfully implemented in Cicerone library that I would like to present you. The main difference of the Cicerone from the other navigation solutions (Magellan, Flow, etc.) is that it is a library and not a framework. You don’t need to extend any classes of the library. Cicerone is only responsible for the transmission of navigation commands to the Android framework and for the keeping their order when the application is sent to the background. As a result, it is easy to integrate Cicerone into any application even if it has been already shipped and works in production.

A little bit about the internals 🛠️

Here is a diagram showing how the library works:

The Presenter calls the Router’s transition method. The router sends the navigation commands to the buffer, which will save them in case if the application is sent to the background. From the Buffer, the commands go to the Navigator, which usually lies in an Activity, and here happens the actual screen switching. Details about how the library works are described on the github. Welcome to the discussion, you can ask all your questions there! 😏

Practice ⚙️

The library’s API created in such way that the use of Cicerone together with Kotlin would make anyone happy! 🎉

Let’s see how it looks like.

Simple navigation 🚲

The most common case is simple navigation between screens back and forth.

You can achieve it in a next way (as we said above, commands start from Presenter):

Navigator class is already implemented, so you just need to describe how to create screens depending on given keys.

Animations 🔥

The main question after the first release was how we can add animation of Fragment changes. Since the version 2.0 we can add animations to transactions in a next way:

Soon, you will be able to add animations for Activity transitions too.

OnSmthResult 🕶

The second most frequently asked question is how to return a result from one screen to the previous. And now we do cover it too!

Nested Navigation 🤖

The most complex case is the independent navigation stack in different tabs (like in Instagram). Cicerone helps to solve the task easily. However, the description of the process will be too wordy, so I suggest you to look at the sample to the library, where we have an example of such pattern.

Application 👊

There are many cases showing Cicerone in an MVP-based application. However, it works well in MVVM and even in the simplest applications without presentation logic separation. If you think that it is too complicated, just look at the source code and you will see how simple it is. Moreover, you can easily extend the library to better handle your particular cases.

I hope you will enjoy it and I am looking forward to your pull requests! 😉

P.S.:

Thanks to Artur for help with publishing.