The Navigation Architecture Component Tutorial: Getting Started
In this tutorial, you’ll learn how to use the Navigation Architecture Component, which simplifies the implementation of navigation in Android apps. By Ivan Kušt.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
The Navigation Architecture Component Tutorial: Getting Started
25 mins
- Why Do You Need Yet Another Component?
- Getting Started
- Adding the Navigation Architecture Component
- Navigation Graph
- Destinations
- Declaring a Start Destination
- NavHost Interface
- Connecting Destinations
- Actions
- Navigation Editor
- Navigating From a Menu
- Passing Data and Animating Actions
- Passing Data Between Destinations
- Adding Transitions
- Types of Destinations
- Adding New Destination Types
- Common Destinations
- Deep Links
- Nested graphs
- Conditional Navigation
- Where to Go From Here?
Common Destinations
To reuse actions, you can declare them outside of any destination
tags. Such actions are called global actions.
You'll now make showing author details a global action.
Open nav_graph.xml. Move the @+id/actionShowAuthor
action from the @+id/workDetailsFragment
destination to instead be a direct child of the navigation
tag. Now open BookDetailsFragment
and replace
// TODO implement navigation to author details
with the following:
findNavController().navigate(
R.id.actionShowAuthor,
AuthorDetailsViewModel.createArguments(it)
)
Add the missing import statements:
import androidx.navigation.fragment.findNavController
import com.raywenderlich.android.bookmanstreasure.ui.authordetails.AuthorDetailsViewModel
Build and run your app. Now, you can open author details from both the Work details and Book edition details screens.
Deep Links
Deep links are URLs that link to a specific screen or content of your app. Your next task is to create a deep link to the Favorites screen.
Open nav_graph.xml file. Look for the fragment
tags with the @+id/favoritesFragment
ID, and paste this between its tags:
<deepLink app:uri="bookmanstreasure://home/favorites" />
The Navigation architecture component will associate the provided URI with the FavoritesFragment
. Open AndroidManifest.xml and add the following between the sole activity
tags:
<nav-graph android:value="@navigation/nav_graph" />
Add the code to handle deep links at the end of the onCreate()
method in MainActivity
:
findNavController(this, R.id.navHostFragment).onHandleDeepLink(intent)
And, finally, add the following implementation of the onNewIntent()
method to MainActivity
:
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
findNavController(this, R.id.navHostFragment).onHandleDeepLink(intent)
}
Make sure to also add the import statement:
import android.content.Intent
Rebuild the app and open the AndroidManifest.xml
file. Click on the Merged Manifest tab at the bottom of the editor. You'll notice that the Navigation architecture component has been added a few items:
To test deep links, you'll create a new Run configuration for the app.
Under the Run configurations dropdown, select Edit configurations... option.
Click on the + button in the top-left corner and select Android app from the list. This will create a new empty Run configuration for Android app.
Set the following properties for the new configuration:
- Under Name, enter
Deep link test
. - Under Module, select
app
. - Under Launch options select URL
- Under URL, enter
bookmanstreasure://home/favorites
.
Now, click on Apply and then OK.
Select the new configuration from Run configurations dropdown and run it.
The app should open the Favorites screen.
Nested graphs
To enhance readability and reusability, one navigation graph can be embedded into another. Create a new navigation graph named book_nav_graph.xml - use the same steps you used as when creating nav_graph.xml.
Replace the auto-generated content for the navigation
tag with this:
<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/bookDetailsGraph"
app:startDestination="@id/workDetailsFragment">
</navigation>
There are two things to note:
-
workDetailsFragment
is set as the start destination. - The ID of the nested graph has been set to
bookDetailsGraph
.
Now, open nav_graph.xml
and move the following actions and destinations to book_nav_graph
:
actionShowAuthor
workDetailsFragment
bookDetailsFragment
authorDetails
In nav_graph.xml and add the following between the navigation
tags:
<include app:graph="@navigation/book_nav_graph" />
Now, open BookSearchFragment
and find:
findNavController().navigate(
R.id.actionBookDetails,
WorkDetailsViewModel.createArguments(it)
)
Replace it with:
findNavController().navigate(
R.id.bookDetailsGraph,
WorkDetailsViewModel.createArguments(it)
)
Note the ID change — you're now pointing to the nested graph. Do the same for FavoritesFragment
, then build and run to make sure everything still works!
Conditional Navigation
The last remaining task is to open the Favorites screen if any books have been favorited.
Open nav_graph.xml and add a new destination for LauncherFragment
:
<fragment
android:id="@+id/launcherFragment"
android:name="com.raywenderlich.android.bookmanstreasure.ui.launcher.LauncherFragment"
android:label="Blank"
tools:layout="@layout/fragment_book_details">
<action
android:id="@+id/actionBookSearch"
app:destination="@id/bookSearchFragment" />
<action
android:id="@+id/actionFavorites"
app:destination="@id/favoritesFragment" />
</fragment>
The XML should feel familiar – it's a fragment destination with two actions.
Update the startDestination
attribute of the navigation
tag to be the following:
app:startDestination="@+id/launcherFragment"
Next, open the LauncherFragment
and find:
//TODO implement navigating to Search or Favorites
Replace it with the following:
val destination = if (it.hasFavorites()) {
R.id.actionFavorites
} else {
R.id.actionBookSearch
}
findNavController().navigate(
destination,
null,
NavOptions.Builder().setPopUpTo(
R.id.launcherFragment,
true
).build()
)
Add the following imports:
import androidx.navigation.fragment.findNavController
import androidx.navigation.NavOptions
This will check if there are any favorites and show the appropriate screen. Note the third argument passed to the navigate()
function. It specifies navigation options. In this case, it clears the backstack to prevent the user from navigating back to the LauncherFragment
.
NavOptions.Builder
official documentation.Now, build an run the app. Search for a book, tap on one of the results and add a favorite by tapping on the ❤︎ icon on the top-right.
Exit the app, then launch it again. You should land on the Favorites screen.
Where to Go From Here?
You can download the final project using the Download materials button at the top or bottom of the tutorial.
Now you know how to use the Navigation architecture component! Even though it is still in beta, it eases development quite a bit.
A great place to find more information is the official documentation from Google. Also be sure to check out our screencast on the topic.
If you have any questions or tips for others on using the Navigation architecture component, please join in on the forum discussion below!