Using The Navigation Architecture Component in Android Jetpack (Kotlin) — Now updated to 1.0.0

Android’s answer to Storyboards in iOS

Prasannajeet Pani
Android Nuggets
7 min readSep 3, 2018

--

Table of Contents

Note: The GitHub codebase provided at the end of the article has now been updated to use Navigation 1.0.0. The diff commit for the same can be found here. The article in process of being updated to reflect the changes.

Introduction

Android application development has taken a huge stride over the last few years. I started programming Android applications back in the days when writing the entire code in Activities was considered the **right** way of doing things. Since then, we have had Fragments come along, then came the idea of MVP/MVVM/MVI architectures, Reactive programming, Event Bus, Clean Architecture etc.

Google itself has decided to promote the Model-View-ViewModel approach to write applications in and has advocated it as part of their with Android Architecture Components framework which was further expanded into Android Jetpack during Google I/O 2018. Among the concepts introduced include ViewModel, LiveData, Room Database, WorkManager and Navigation. This article explains the last.

FYI: If you would like to get a good understanding of how Android Jetpack and Architecture Components work, here is a project called Sunflower currently under active development by Google and written in Kotlin that I would highly recommend.

Find the Github repo of an expanded sample app I created using the steps mentioned below

The core aspect of the Navigation Component lies in the application’s navigation graph. To understand what a navigation graph is we have to understand the concept of destinations. As per Google:

A destination is any place you can navigate to in your app. While destinations are usually Fragments representing specific screens, the Navigation Architecture Component supports other destination types:

  • Activities
  • Navigation graphs and subgraphs — when the destination is a graph or subgraph, you navigate to the starting destination of that graph or subgraph
  • Custom destination types

A set of destinations comprise your application’s navigation graph. In addition to destinations, a navigation graph has connections between destinations called actions.

Below image shows you the destinations in the sample app I ended up creating for myself. We will be creating a much simpler 2 fragment navigation graph in this tutorial

Navigation Graph for my Sample app

Enough talk. Lets see some code!

Setup

Step 0:

You need to have Android Studio 3.2 RC or above in order to work with any Android Jetpack components including Navigation (download). Also, for the purposes of this tutorial, knowledge of Kotlin is a must.

Step 1:

Create a new Android project, add a blank activity and let the gradle build finish

Step 2:

Add the following dependencies to your existing app/build.gradle file and perform a gradle sync. This should go in your dependencies{} block

Dependencies required for Navigation Architecture Component

Additionally, in order to support passing of values between the views involved in a navigation we would need to add the typesafe gradle plugin.

Add the navigation-safe-args-gradle-plugin in the project level build.gradle’s dependencies{} tag. The file should look something like this in its entirety.

After Adding navigation-safe-args-gradle-plugin

Then in the app/build.gradle we have to add the following gradle plugin before the android{} block

apply plugin: 'androidx.navigation.safeargs'

Step 3:

For implementing Navigation, Android has introduced a new resource type called Navigation. Right click on the res directory and choose New -> Android resource file. Choose a title for the file and select Navigation from the Resource type dropdown. It should look something like this:

Adding a navigation graph file

Once you have created the navigation xml file it will look something like this

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/welcome_nav_graph">

</navigation>

Step 4:

If you haven’t already, go to File — Settings (Android Studio — Preferences in Mac) and click on Experimental on the left menu. Select Enable Navigation Editor on the right.

Enable Navigation Editor

Step 5:

In you navigation graph xml file go to Design view and click on the New Destination icon and it should show something like this.

Create blank destination

We will create two fragments here by clicking on the Create Blank Destination button. MainFragment and DestinationFragment. Once you have created both the fragments here your navigation xml file will look like this

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/welcome_nav_graph"
app:startDestination="@id/mainFragment">

<fragment
android:id="@+id/mainFragment"
android:name="com.praszapps.mysamplenavapp.MainFragment"
android:label="fragment_main"
tools:layout="@layout/fragment_main" />
<fragment
android:id="@+id/destinationFragment"
android:name="com.praszapps.mysamplenavapp.DestinationFragment"
android:label="fragment_destination"
tools:layout="@layout/fragment_destination" />

</navigation>

And your design view should look something like this

The home icon on mainFragment signifies that its the starting point of your navigation. This usually is the fragment/activity that shows first when you launch the app.

In the next section, we will setup navigation from mainFragment to destinationFragment and pass a String value between them

Adding Action

In order for the framework to understand which destination it needs to go to from the source you have to specify an action. You will have to add the action tag inside your source/home fragment from where the navigation is to be performed.

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/welcome_nav_graph"
app:startDestination="@id/mainFragment">

<fragment
android:id="@+id/mainFragment"
android:name="com.praszapps.mysamplenavapp.MainFragment"
android:label="fragment_main"
tools:layout="@layout/fragment_main" >
<action
android:id="@+id/action_mainFragment_to_destinationFragment"
app:destination="@id/destinationFragment" />

</fragment>
<fragment
android:id="@+id/destinationFragment"
android:name="com.praszapps.mysamplenavapp.DestinationFragment"
android:label="fragment_destination"
tools:layout="@layout/fragment_destination" />
</navigation>

Adding Arguments

Let’s say you are passing a name from your MainFragment into DestinationFragment and in the latter you show a message “Welcome $name”. I order to get the name from the source to the destination we need to pass it as an argument. You may add multiple such arguments.

Setting an Argument type in turns results in invoking that Fragment using the value passes as a Bundle argument. We will see how in the next section.

In the navigation XML, add an <argument/> tag to the destination fragment. There are 3 attributes an argument can take

  1. android:name— The identifier for the argument
  2. app:argType— What datatype it is. Currently it supports inferred, integer, string, reference
  3. android:defaultValue (optional) — A default value that the recieving fragment will get in case the source fragment does not pass any value

With that done, your navigation XML file will now look like this.

And thus the navigation is setup, the framework knows what is the source, the destination and what data is to be passed along during navigation. Now let’s go and create a simple UI and stitch it all up with some Kotlin code

Creating The XML Layouts

We will create a very basic UI wherein we have an EditText and a Button in the MainFragment where we enter our name. Upon button click, we pass the name from MainFragment to DestinationFragment to be shown as “Welcome $name”.

Below is how my layouts look, feel free to copy it over to your project

And finally the Activity layout where will add the MainFragment

Some Kotlin Code To Get It All Working

Step 1: MainActivity

Add the MainFragment to the MainActivity in the onCreate() function. We will use NavHostFragment.create() to get our NavHostFragment which we then pass onto the FragmentTransaction to invoke the Fragment

setPrimaryNavigationFragment function is added to set up the backstack navigation of the Fragment notifying MainFragment as the host.

Step 2: MainFragment

In the MainFragment, we need to perform the action on the button click to navigate to DetailFragment taking along with it the name that’s entered in the EditText.

In the onViewCreated method of the Fragment, we get the action object that we added in the navigation XML under <action> tag.

val action = MainFragmentDirections.actionMainFragmentToDestinationFragment()

In this action we will add the name that’s entered in our EditText. This value will then be passed into the DestinationFragment as an argument

action.setNameToShow(enterName.text.toString())

Finally, we invoke the NavController to perform the navigation

findNavController().navigate(action)

I have added input validation alongwith the above code and my MainFragment looks something like this at the end of the step

Step 3: DestinationFragment

In the DestinationFragment we will need to retrieve the argument passed and set it as the text in the TextView we have placed in the layout

We will get the arguments for the class navigated to by using the {ClassName}Args.from() function. For Example, in this case we get the name that was passed from MainFragment in this fashion.

val name = DestinationFragmentArgs.fromBundle(arguments).nameToShow

Here nameToShow is the argument name that we had set in navigation XML file.

The final DestinationFragment class looks like this:

Conclusion

And that’s it! Once everything is set up, just run the app in the emulator and you would see the Navigation Framework work its magic for yourself.

Like the article? Well slap on those claps!!!

Cheers!!!

--

--

Prasannajeet Pani
Android Nuggets

Android Developer to fund my Photography to feed my soul. My alter ego is a stand-up comedian. IG: http://instagram.com/prasan.photos