Getting started with Navigation Component

Bhoomi Shah
Simform Engineering
6 min readJun 28, 2021

--

Android Jetpack, introduced at Google I/O 2018, was launched to build better applications using best practices and recommended architecture. Jetpack has brought several components and Navigation is one of them. And it’s never too late to learn and adapt to something new.

Navigation refers to the interactions that allow users to navigate across, into, and back out from the different pieces of content within your app. We usually do navigation with activities and fragments.

However, Google recommends the Single Activity Architecture moving forward when using Jetpack.

Firstly why fragments over activities?

Fragments are reusable components, build inside an activity, with their own layout interface and lifecycle. Passing data between fragments has been an easier task than activities. Fragments are also used for multi-pane UI such as viewpager and bottom navigation.

Traditionally navigating between fragments

We have been doing navigation using fragment transaction and manager, simply for going from one screen to another.

Here developers need to write complex code to navigate across fragments. It is about time that we switch towards the use of such components that makes developers seamlessly reduce the complex coding practices.

Why navigation components?

Navigation Architecture gets rid of the complex FragmentTransaction by providing its own set of classes to navigate between fragments.

Providing all in one functionality with simple and fewer lines of code:

  • Handles fragment transactions automatically.
  • Default back press handling actions.
  • Type safety when passing information while navigating.
  • Effortless handling of navigation flow for visualizing and editing the fragments.
  • Effortless implementation for animations and Deep linking.

3 Key Concepts:

The Navigation component consists of three key parts that are described below:

  • Navigation graph
  • NavHost
  • NavController

Let’s start!

To begin with, we need to include Navigation support in the project, add the following dependencies to your app’s build.gradle file:

Navigation Graph

It includes connections to your fragments and activities having visual representation.

A navigation graph is a resource file that contains all of your destinations and actions. The graph represents all of your app’s navigation paths.

It is an XML file that can be created in the res folder. First set the title for the file and choose Navigation from the Resource type dropdown. Now that we have an empty nav_graph.xml file, we need to create two fragments which we are going to use to navigate in between, namely FragmentOne and FragmentTwo.

As an above image, we need to add destinations in the navigation graph which we will be navigating to and from.

As shown above, we can directly add fragments to the graph via design and connect the first fragment to the second one by dragging the line. After adding these destinations our nav_graph.xml file will look like below:

The above code can also be written directly without any need of the Design Editor.

Inside the Navigation Graph XML tag, you must specify the app:startDestination=”@id/fragmentOne”. The application gets launched there.

NavHostFragment

Remember the time we used to use container inside our activity to fill in fragments? Well, the Navigation Host Fragment does the same as we define it in activity_main.xml file as below:

Here the app:navGraph: determines which Navigation Graph will be associated with the Navigation Host and app:defaultNavHost=”true” ensures that the Navigation Host intercepts the system back button when pressed.

Now that we have our graph ready with its destination to reach, let’s talk about how to navigate to other fragments. To do that we have defined the action tag in our nav_graph.xml file as below, however, to use this action in our fragment we need NavController.

<action
android:id="@+id/action_fragmentOne_to_fragmentTwo"
app:destination="@id/fragmentTwo" />

NavController

We have different ways through which we can navigate to fragments either by using action id or destination fragment id as explained below:

1. Using destination fragment id:

Here we can import androidx.navigation.fragment.findNavController and directly pass the id of destination fragment from the current one when button is pressed.

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

We can also navigate by using the Navigation class method findNavController to similarly pass the destination id as below:

button.setOnClickListener {
Navigation.findNavController(requireActivity(), R.id.fragmentTwo)
}

2. Using action id

Action id refers to the id that is created by your navigation graph. Here action_fragmentOne_to_fragmentTwo can be directly used for navigation.

<action
android:id="@+id/action_fragmentOne_to_fragmentTwo"
app:destination="@id/fragmentTwo" />

Here we can directly pass “action id instead of destination id during navigation as below:

3. Using createNavigateOnClickListener:

Navigation class has createNavigateOnClickListener method, it supports both navigating using “action id and “destination fragment id” as a first parameter. Whereas second parameter is optional to pass the bundle arguments if any.

Great! now we know the ways using which we can navigate to different fragments, however, we need one more thing that is how to pass arguments to other fragments? Just like we used to do it traditionally? Well, the navigation component has now a built-in way to pass arguments directly through your XML.

That’s right, in our nav_graph.xml design editor attributes tab, we can add arguments by clicking + on selected fragment, there you can see the dialog, after adding values we can see the XML updated similarly as below:

<argument
android:name="title_name"
app:argType="string"
android:defaultValue="Two" />

We can also pass more arguments directly from fragment using bundle even if it’s not added inside xml

val bundle=Bundle()
bundle.putBoolean(IS_FROM_FIRST,true)
Navigation.createNavigateOnClickListener(R.id.fragmentTwo,bundle)

Safe Arguments

Navigation component also offers the type safety for passing arguments.

Safe Args is strongly recommended for navigating and passing data because it ensures type-safety. It is a Gradle plugin of navigation components, built specifically for generating simple objects and builder methods to simplify the code usage. To integrate it we need to add following in your top level gradle file:

classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"

and also add below line to module level gradle file:

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

After successfully sync and adding the arguments in your xml file, you will be able to see a class auto-generated for your fragmentOne named FragmentOneDirections

Similarly, to retrieve the arguments passed at receiver end, the second fragment has auto generated class named SecondFragmentArgs

Here we don’t need to check the type and cast the arguments as we are ensured that the arguments passed are type-safe. For our example, the first argument is a string and the second is boolean.

One thing to note while working with navigation is that when we add a new fragment into the stack, behind the scenes Navigation Component replaces the current fragment instead of adding for a better memory optimization approach. Navigation Component is made keeping in mind to use it with LiveData and ViewModel for higher-level abstraction that architecture framework provides. That’s how Google pushes us to use these components in order to build overall better applications.

Start using navigation components if you are not, you will find it a very delightful change. Don’t miss to hit the clap icon👏 and feel free to share your views in the comment section below.

Happy Navigating!🧭

--

--

Bhoomi Shah
Simform Engineering

Senior Android Developer | Computer Science Student| #Android #Kotlin #Java.