Navigation Component 101: for those who skipped all the tutorials

Anton Uryvskii
2 min readJan 20, 2021

This story is for those who still don’t know much about the Navigation Component. Here we will run through the main elements of the library and see how it all looks.

You are now in the first part of a large story about the Navigation Component in a multi-module project. If you are already familiar with the basics, then I recommend going further to the parts:

TL;DR.:

To organize navigation in the app using the Navigation Component, you need to:

  1. Create a Graph;
  2. Add destinations;
  3. Add transitions between them;
  4. Add nested graphs if necessary;
  5. Putting all this mess together in navhost;
  6. Specify transitions in your code.

Basic navigation components

1. Navigation Graph is the main unit of navigation where you will put your destinations and the transitions between them. The graph is created in a separate xml file in the res/navigation folder. Do not forget to specify start destination of graph to let it know which screen should be shown first

2. Destination represents the UI unit on the graph (Fragment/Activity/Dialog/nested graph).

3. Action is a transition between the destinations of the graph. It can be either directed (from one screen to another) or global (without a start position).

4. Nested Graph: if one graph is not enough or it’s very big, you can split them into several and reuse one graph in another using the <include> tag.

5. Navhost — the main host of the navigation, that handles destination swap. For correct work you need to set the name field of the container to androidx.navigation.NavHostFragment and set its navigation graph. Here is a nav host example:

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

6. NavController — an object that is responsible for destination swap. In fact, NavController is a router with which we can navigate between fragments, send parameters, set additional transition options, animations, shared elements, etc.

Destination transitions

There are two ways to specify transition: Action and DeepLink.

Transition with an Action

How it looks:

<action
android:id=”@+id/action_to_user_details”
app:destination=”@id/userDetailsFragment”
app:enterAnim=”@anim/add_fragment_animation”
app:exitAnim=”@anim/pop_fragment_animation”
app:popEnterAnim=”@anim/pop_enter_animation”
app:popExitAnim=”@anim/pop_exit_animation”>

Transition call:

navController.navigate(
R.id.action_to_user_details,
Bundle().apply {putString(USER_ID, userId)}
)

Obtaining the arguments in target destination:

private val userID by lazy {
arguments!![USER_ID]
}

Transition with DeepLink

How it looks:

<deepLink 
app:uri=”app://customUri?parameter={parameterName}”
/>

Transition call:

navController.navigate(
Uri.parse(“app://customUri?parameter=$reason”)
)

Obtaining the arguments in target destination:

private val refundId by lazy {
arguments?.getString(“parameter”, null)
}

That’s it! Quite simple, right? Now let’s dive into how the Safe Args plugin works and what it does, and get down working with the Navigation Component in a multi-module project with Safe Args and iOS-like multistack navigation.

--

--