Android

A practical approach of Navigation Jetpack

By August 7, 2019 February 24th, 2020 2 Comments

Introduction

Google is making big efforts to ease the way developers create applications. Lately Android Jetpack has been released allowing the developers to focus on what a matters and standardizing the way developers do things.

The goal of this post is to show how I used in a commercial App the new Navigation, avoiding any code that you can find elsewhere. So you won’t find how to configure the Navigation library or the class description of any object involved (you can find detailed doc for that in official doc ).

Approach

To start, let’s be clear on how the default Navigation works (this is a question I have seen posted many times).

Note: The Navigation Architecture Component is designed for apps that have one main activity with multiple fragment destinations. The main activity “hosts” the navigation graph. In an app with multiple activity destinations, each additional activity hosts its own navigation graph. Modifying an activity to host navigation is discussed later in this document.

Let’s see a real example. The application I was developing for my client had different clear parts that I could divide in what I call “process”.

A process is somewhere the user can go through different screens that share a meaning (normally that is mapped in an Activity). Processes have a beginning and an end. In this App I had:

  • Signup and Login
  • Oboarding User
  • User logged area

All these processes were composed by several screens. The user could go back and forth. So for each process I created an Activity holding its nav graph xml.

Onboarding user nav graph xml representation

This icon marks the first fragment to be shown.

Arrows in the graph are called Actions and they are used to navigate to one screen or another. You can easily:

  • Pass values between fragments (Automatically creates the bundle). Use Safe-args for a better usage.
  • Set in/out animation transitions.
  • PopTo characteristics. I talk about this later in this article.

Using default NavHost and NavController will navigate along fragments within an Activity.

The layout of the OnboardingActivity holds the NavHost containing the following nav graph xml.

<fragment
    android:id="@+id/fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:defaultNavHost="true"
    app:navGraph="@navigation/nav_graph_onboarding"/>

In order to navigate along the graph you need to use the Actions with the NavController. Here it is how I used it in my code:

Navigation.findNavController(view)
.navigate(R.id.action_onbardingNameFragment_to_onboardingPhotoFragment)

or

view.findNavController()
.navigate(R.id.action_onbardingNameFragment_to_onboardingPhotoFragment)

Note that in order to find the NavController a view it is passed. This view needs to be inside the hierarchy of the layout hosting the nav graph. Since actually what findNavController does is walk along the parents of the view to find out the object tagged as the NavController.

In the previous example, the user will navigate only on one straight direction until the “cardStackActivity” (where the user plays the game).

Once we use the Action to the “cardStackActivity”, the Navigation will scape from the current layout (it will inflate the layout “cardStackActivity” ).

This new inflated layout holds another different nav graph in order to continue the navigation inside that Activity. So you will be able to start using the Actions within the new nav graph.

Backstack

Navigation manages the fragment stack itself, so everytime the user presses the backbutton, the current fragment is popped out, going back to the previous one in the backstack. In order let the Navigation manage the backstack set app:defaultNavHost="true" in the NavHost

A mistake I made was to create a circle to navigate back to the main screen after passing through some screens.

In this application, when the user reaches the matches or carrosuel Fragment, user had to go back to first screen. As you can see in the blue actions leads the user back to the first fragment. But that is wrong.

Instead I needed to use Pop to. It defines how to go back to a certain point.

PopBehaviour to pop back to a certain point
Pop to First Fragment without Inclusive

Imagine you want to pop the fragment until the first one. Checking Inclusive will pop also that fragment. So being this first fragment the last one in the backstack, the Activity will close.

Pop to First Fragment with Inclusive checked

Conclusion

Navigation Jetpack helped me to organize in terms of code and visualy what the user could do in the App.

I had my problems on using it. Since before using the Navigation Jetpack, I was used to use a Navigation object that was in charge of starting activities and I could do it pretty much where I wanted (I had my rules).

Now Navigation Jetpack forces me to keep it tight and to make code much more clear, since I will only be able to Navigate to a screen from a Fragment or Activity, since you need the view or context that holds the current nav graph.

At least I like to be forced to do so and not mess around with presenters o models for that.

The navigation graphs helps to have a global view of the flow. What the user can do, avoiding hidden flows inside the App.

Ernie

Author Ernie

More posts by Ernie

Join the discussion 2 Comments

  • Nono F. Carballo Escalona says:

    Hi Ernesto,

    Could you share a repository with the source code, please?

    Best regards.

    • Ernie says:

      Hi Nono,
      I am preparing next article and will include examples on github. These specific examples were for a commercial app. Let me know if you need some clarification about any detail.