Navigation Component for Android Part 2: Graphs and Deep Links

In this tutorial you’ll use the Jetpack Navigation component to write an Android app utilizing graphs and deep links to navigate through different screens. By Meng Taing.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Seeing What You’ve Sent

Open SentFragment.kt. To see the letters you’ve sent, you need to assign the same nav-graph-scoped ViewModel to lettersViewModel. Assign the value to lettersViewModel as follows:

private val lettersViewModel: LettersViewModel by navGraphViewModels(R.id.nav_graph)

No surprise here. It’s the same old code.

Next, handle the click on a RecyclerView item. Add the following code to adapter.setItemClickListener:

findNavController().navigate(SentFragmentDirections.presentLetter(Gson().toJson(it)))

So far, you’ve used navigation by fragment id. In the line of code above, you use the generated SentFragmentDirections class.

Navigation component generates a class for each fragment which has an action to another fragment. The name of the generated class is the name of the originating destination, appended with the word Directions.

presentLetter is the id you gave the action from SentFragment to PresentationFragment. Here, you use it to pass the safe args.

Finish the next step before running your app. It’ll be a quick one.

Seeing What You’ve Received

Repeat the same steps from SentFragment in InboxFragment. In InboxFragment.kt, Assign the value to lettersViewModel as follows:

private val lettersViewModel: LettersViewModel by navGraphViewModels(R.id.nav_graph)

Add the following code to adapter.setItemClickListener:

findNavController().navigate(InboxFragmentDirections.presentLetter(Gson().toJson(it)))

Now you can test the whole flow of sending and receiving a love letter. You should see letters in the SentFragment and InboxFragment. Clicking any letter in the list should open the PresentationFragment.

Inbox To Sent Screens

Nested Graph

If you’re building a large-scale app, you should create different graphs for modularization and reusability. Similar to layout files, you can nest a new graph in the current graph.

You’ll create another graph for Privacy Policy and Terms of Service. Create another navigation graph in the same location as nav_graph.xml. Name it agreement_graph.xml.

  1. Add PrivacyPolicyFragment and TermsOfServiceFragment to Navigation Editor.
  2. Set PrivacyPolicyFragment as the home fragment.
  3. Connect PrivacyPolicyFragment to TermsOfServiceFragment.
  4. Switch to Text view and change their label to proper name from String resource.
  5. Set the id of the navigation graph to android:id="@+id/agreement_graph".
<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/agreement_graph"
  app:startDestination="@id/privacyPolicyFragment">

  <fragment
    android:id="@+id/privacyPolicyFragment"
    android:name="com.raywenderlich.android.loveletter.agreement.PrivacyPolicyFragment"
    android:label="@string/privacy_policy"
    tools:layout="@layout/fragment_privacy_policy">
    <action
      android:id="@+id/action_privacyPolicyFragment_to_termsOfServiceFragment"
      app:destination="@id/termsOfServiceFragment"/>
  </fragment>
  <fragment
    android:id="@+id/termsOfServiceFragment"
    android:name="com.raywenderlich.android.loveletter.agreement.TermsOfServiceFragment"
    android:label="@string/terms_of_service"
    tools:layout="@layout/fragment_terms_of_service"/>
</navigation>

Agreements Graph

Next, switch to nav_graph.xml. Add the nested agreement_graph the same way you added the other fragments in Design view. That’s by clicking the new destination button, you don’t have to connect any fragment to the nested graph.

Now, how do you navigate to the nested graph?

Nested Agreements Graph

Creating Implicit Deep Link With URI

The answer is simple: Use a deep link. More precisely, use an implicit deep link. Implicit deep links allow you to navigate to any fragment by URI.

Go back to agreement_graph.xml. In Design view, with PrivacyPolicyFragment selected, find the Deep Links section on the Attributes panel.

Deep Link Attribute

Click the + sign, and add the following deep link in the URI textfield:

loveletter://agreement/privacy-policy

Add Privacy Policy Deep Link

Repeat the steps above to add another deep link for TermsOfServiceFragment:

loveletter://agreement/terms-of-service

Add Terms of Service Deep Link

Do you remember the Privacy Policy and Terms of Service drawer menu items at the beginning of the tutorial? Now that everything is connected, you can test them out.

Open Agreement Screens

Handling Web URL Deep Link

Assume you own http://www.loveletter.com. When someone sends a love letter, you want to embed a link in the email.

If the recipient clicks the link on his phone app client, and his phone has Love Letter app installed, the phone should prompt the recipient to launch the app to see the letter. Otherwise, the recipient should be able to open the letter on any web browser.

Open AndroidManifest.xml. Add the following line inside <activity> and above <intent-filter>:

<nav-graph android:value="@navigation/nav_graph" />

This is a crucial step that’s easy to forget. If you have another deep link to another navigation graph, remember to add the graph here.

Next, go to nav_graph.xml. Add the following deep link to PresentationFragment:

www.loveletter.com/letter/{letter}

Don’t include http:// or https:// for web URL. {letter} is the encoded-URL which should passed to PresentationFragment.

Does the URL looks familiar? You saw it in the Logcat when you clicked the SEND button on CreateLetterFragment. Here, you configure it to handle that link.

With all the puzzle pieces complete, you can test the deep link like this:

  1. Go to Run ▶ Edit Configurations.
  2. Add new a Android App configuration.
  3. Name it letter-deeplink.
  4. Select Module: app.
  5. Select Launch: URL.
  6. Paste in the URL you got from Logcat after you clicked the SEND button.
  7. Click OK to finish.

Run Configurations

Change the run configuration from app to letter-deeplink and run it.

Launch App With Deep Link

Where to Go From Here?

Congrats! You should now be able to navigate to any fragment in any way by controlling the actions and destinations with the Navigation component.

You can download the finished project with the Download materials button at the top or bottom of the tutorial.

Jetpack Navigation component also works with Bottom Navigation. Try adding Bottom Navigation and connecting it to the navigation controller with NavigationUI.setupWithNavController(...).

You can find additional examples of Navigation at the official Android Developer website. You can also find a list of guidelines for Navigation on Android Developers blog.

If you have any questions or comments on what you’ve learned, join the forum discussion below!