Android – An Overview Of Navigation Component In Android

Hello Readers, CoolMonkTechie heartily welcomes you in this article.

In this article, we will learn about an overview of navigation component in Android. We will discuss about navigation graph and how to pass arguments safely.

The Navigation Architecture Component simplifies implementing navigation, while also helping you visualize our app’s navigation flow. The library provides a number of benefits, including:

  • Automatic handling of fragment transactions
  • Correctly handling up and back actions by default
  • Default behaviors for animations and transitions
  • Deep linking as a first-class operation
  • Implementing navigation UI patterns (like navigation drawers and bottom nav) with little additional work
  • Type safety when passing information while navigating
  • Android Studio tooling for visualizing and editing the navigation flow of an app

The Navigation component requires Android Studio 3.3 or higher and is dependent on Java 8 language features.

A famous quote about learning is :

” I am still learning.”


So Let’s begin.


Overview

The Navigation Component consists of three key parts:

  1. Navigation Graph (New XML resource) — This is a resource that contains all navigation-related information in one centralized location. This includes all the places in our app, known as destinations, and possible paths a user could take through our app.
  2. NavHostFragment (Layout XML view) — This is a special widget you add to our layout. It displays different destinations from our Navigation Graph.
  3. NavController (Kotlin/Java object) — This is an object that keeps track of the current position within the navigation graph. It orchestrates swapping destination content in the NavHostFragment as we move through a navigation graph.


Navigation Component Integration

Just include the following code in the dependencies block of our module-level build.gradle file:

def nav_version = "2.2.2"
  // Java language implementation
  implementation "androidx.navigation:navigation-fragment:$nav_version"
  implementation "androidx.navigation:navigation-ui:$nav_version"

  // Kotlin
  implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
  implementation "androidx.navigation:navigation-ui-ktx:$nav_version"


Navigation Graph

First, we will create a file that will contain our navigation graph. In the res, directory create a new android resource file as follows:

This will create an empty resource file named nav_graph.xml under the navigation directory.

For example, we have two fragments named FirstFragment and SecondFragment. FirstFragment has a button on click of which we will navigate to the SecondFragment.

We define these fragments in the navigation graph as below:

<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/nav_graph"
    app:startDestination="@id/nav_first_fragment">

    <fragment
        android:id="@+id/nav_first_fragment"
        android:name="app.navigationcomponentexample.FirstFragment"
        tools:layout="@layout/fragment_first">

        <action
            android:id="@+id/action_first_to_second"
            app:destination="@id/nav_second_fragment"/>

    </fragment>

    <fragment
        android:id="@+id/nav_second_fragment"
        android:name="app.navigationcomponentexample.SecondFragment"
        tools:layout="@layout/fragment_second"/>

</navigation>

Here the root tag named navigation has a parameter called app:startDestination which has the id of our first fragment. This defines that the first fragment will be loaded in the NavHostFragment automatically.

The Navigation Component introduces the concept of a destination. A destination is any place you can navigate to in your app, usually a fragment or an activity. These are supported out of the box, but we can also make our own custom destination types if needed.

Notice that for first fragment we have defined an action with the following attributes:

android:id="@+id/nav_first_fragment"
app:destination="@id/nav_second_fragment"

Each action should have a unique id which we will use to navigate to the required destination.

Here the destination points to the id of the second fragment defined in the nav graph, which means that with this action we will navigate to the second fragment.

After this step when we open the nav_graph.xml and switch to the design tab, it should look like the following:


Navigation Types

With the navigation component, we have multiple ways to navigate :


1. Navigation using destination Id

We can provide the id of the destination fragment to navigate to it, like the following:

button.setOnClickListener {
    findNavController().navigate(R.id.nav_second_fragment)
}


2. ClickListener

For views, we can also use createNavigateOnClickListener() method from the Navigation class as follows:

button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.nav_second_fragment, null))


3. Navigation using Actions

As in the above nav graph, we have defined action in the first fragment, we can use the id of the action as follows:

button.setOnClickListener {
    findNavController().navigate(R.id.action_first_to_second)
}

The last piece required is to define the NavHostFragment. It is a special widget that will display the different destinations defined in the nav graph. Copy the following code and paste it in the layout of the activity in which we want to load our FirstFragment.

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

android:name="androidx.navigation.fragment.NavHostFragment" defines the NavHostFragment used by NavController

app:defaultNavHost="true" is simply stating that you want this to be the NavHost that intercepts and works as the back button on our device.

app:navGraph="@navigation/app_navigation" associates the NavHostFragment with a navigation graph. This navigation graph specifies all the destinations the user can navigate to, in this NavHostFragment.

After these steps when we run the app, FirstFragment should be loaded automatically and when we click the button it should open the SecondFragment. Also when we press the back button, it should navigate back to the FirstFragment.


Safe Arguments

The navigation component has a Gradle plugin, called safe args, that generates simple object and builder classes for type-safe access to arguments specified for destinations and actions.

Safe args allows getting rid of the code like below:

val username = arguments?.getString("usernameKey")

with the following:

val username = args.username


Safe Arguments Integration

Add the following code in the top-level Gradle file:

classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.2.2"

Now import the plugin into the module level Gradle file:

apply plugin: 'androidx.navigation.safeargs.kotlin'

Now the safe args plugin is active in our project. We will add 2 arguments to be passed to the SecondFragment from the FirstFragment. We will define arguments in the nav graph as follows:

<fragment
    android:id="@+id/nav_second_fragment"
    android:name="app.navigationcomponentexample.SecondFragment"
    tools:layout="@layout/fragment_second">

    <argument
        android:name="arg1"
        app:argType="integer"
        android:defaultValue="0"/>
    <argument
        android:name="arg2"
        app:argType="string"
        android:defaultValue="default"/>

</fragment>

Here the first argument is named arg1 which is of type Integer and has the default value of 0. Similarly, the second argument is named arg2 which is of type String and has a default value of “default”.

After we define these arguments, Gradle will generate a class named SecondFragmentArgs which can be used in SecondFragment to retrieve the arguments in the following way.

val safeArgs: SecondFragmentArgs by navArgs()

val arg1 = safeArgs.arg1
val arg2 = safeArgs.arg2

Here we are assured that arg1 is of type Integer and arg2 is of type String and thus we don’t need to cast them to their respective types.

Now in order to pass these arguments from the FirstFragment, another class named FirstFragmentDirections gets created which has a static method named actionFirstToSecond. This can be used to pass the arguments in the following way.

button.setOnClickListener {
    val directions = FirstFragmentDirections.actionFirstToSecond(arg1 = 1234, arg2 = "abcd")
    findNavController().navigate(directions)
}

That’s all is required to pass arguments in a type-safe manner. Apart from the inbuilt types, we can also define the custom type of arguments by creating a Parcelable class.

That’s all about in this article.


Conclusion

In this article, we learned about an overview of navigation component in Android. We have also discussed about navigation graph and how to pass arguments safely in Android.

Thanks for reading ! I hope you enjoyed and learned about Navigation Component Concept in Android. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

Loading

Leave a Comment