Design your navigation graph

The Navigation component uses a navigation graph to manage your app's navigation. The navigation graph is a data structure that contains each destination within your app and the connections between them.

Destination types

There are three general types of destinations: hosted, dialog, and activity. The following table outlines these three destination types and their purposes.

Type

Description

Use cases

Hosted

Fills the entire navigation host. That is, the size of a hosted destination is the same as the size of the navigation host and previous destinations are not visible.

Main and detail screens.

Dialog

Presents overlay UI components. This UI is not tied to the location of the navigation host or its size. Previous destinations are visible underneath the destination.

Alerts, selections, forms.

Activity

Represents unique screens or features within the app.

Serve as an exit point to the navigation graph that starts a new Android activity that is managed separately from the Navigation component.

In modern Android development, an app consists of a single activity. Activity destinations are therefore best used when interacting with third party activities or as part of the migration process.

This document contains examples of hosted destinations, which are the most common and fundamental destinations. See the following guides for information on the other destinations:

Frameworks

Although the same general workflow applies in every case, how exactly you create a navigation host and graph depends on the UI framework you use.

  • Compose: Use the NavHost composable. Create a NavGraph to it using the Kotlin DSL. You can create the graph in two ways:
    • As part of the NavHost: Construct the navigation graph directly as part of adding the NavHost.
    • Programmatically: Use the NavController.createGraph() method to create a NavGraph and pass it to the NavHost directly.
  • Fragments: When using fragments with the views UI framework, use a a NavHostFragment as the host. There are several ways to create a navigation graph:
    • Programmatically: Use the Kotlin DSL to create a NavGraph and directly apply it on the NavHostFragment.
      • The createGraph() function used with the Kotlin DSL for both fragments and Compose is the same.
    • XML: Write your navigation host and graph directly in XML.
    • Android Studio editor: Use the GUI editor in Android Studio to create and adjust your graph as an XML resource file.

Compose

In Compose, use the NavHost composable to create your navigation graph. Consider the following example:

val navController = rememberNavController()

NavHost(navController = navController, startDestination = "profile") {
    composable("profile") { Profile( /* ... */ ) }
    composable("friendslist") { FriendsList( /* ... */ ) }
    // Add more destinations similarly.
}
  1. The call to the NavHost composable passes a NavController and a route string that corresponds to the start destination.
  2. The lambda passed to the NavHost ultimately calls NavController.creatGraph() and returns a NavGraph.
  3. The calls to NavGraphBuilder.composable() add destinations to the resulting NavGraph.
  4. In this case, the destinations are the Profile and FriendsList composables. The route strings "profile" and "friendslist" become the keys that identify the two destinations.

To better understand the lambda that creates the NavGraph, consider that to build the same graph as in the preceding snippet, you could create the NavGraph separately using NavController.createGraph() and pass it to the NavHost directly:

val navGraph by remember(navController) {
  navController.createGraph(startDestination = "profile") {
    composable("profile") { Profile() }
    composable("friendslist") { FriendsList() }
  }
}
NavHost(navController, navGraph)

Minimal example

A minimal but complete example of a NavController and NavHost working together:

// Define the Profile composable.
@Composable
fun Profile(onNavigateToFriendsList: () -> Unit) {
  Text("Profile")
  Button(onClick = { onNavigateToFriendsList() }) {
    Text("Go to Friends List")
  }
}

// Define the FriendsList composable.
@Composable
fun FriendsList(onNavigateToProfile: () -> Unit) {
  Text("Friends List")
  Button(onClick = { onNavigateToProfile() }) {
    Text("Go to Profile")
  }
}

// Define the MyApp composable, including the `NavController` and `NavHost`.
@Composable
fun MyApp() {
  val navController = rememberNavController()
  NavHost(navController, startDestination = "profile") {
    composable("profile") { Profile(onNavigateToFriendsList = { navController.navigate("friendslist") }) }
    composable("friendslist") { FriendsList(onNavigateToProfile = { navController.navigate("profile") }) }
  }
}

As the snippet demonstrates, instead of passing the NavController to your composables, expose an event to the NavHost. That is, your composables should have a parameter of type () -> Unit for which the NavHost passes a lambda that calls NavController.navigate().

Fragments

As outlined in the preceding sections, when using fragments you have the option to create a navigation graph programmatically using the Kotlin DSL, XML, or the Android Studio editor.

The following sections detail these different approaches.

Programmatically

The Kotlin DSL provides a programmatic way of creating a navigation graph with fragments. In many ways this is neater and more modern than using an XML resource file.

Consider the following example, which implements a two-screen navigation graph.

First it is necessary to create the NavHostFragment, which must not include an app:navGraph element:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

Next, pass the id of the NavHostFragment to NavController.findNavController(). This associates the NavController with the NavHostFragment.

Subsequently, the call to NavController.createGraph() links the graph to the NavController and consequently also to the NavHostFragment:

// Retrieve the NavController.
val navController = findNavController(R.id.nav_host_fragment)

// Add the graph to the NavController with `createGraph()`.
navController.graph = navController.createGraph(
    startDestination = "profile"
) {
    // Associate each destination with one of the route constants.
    fragment<ProfileFragment>("profile") {
        label = "Profile"
    }

    fragment<FriendsListFragment>("friendsList") {
        label = "Friends List"
    }

    // Add other fragment destinations similarly.
}

Using the DSL in this way is very similar to the workflow outlined in the preceding section on Compose. For example, both there and here, the NavController.createGraph() function generates the NavGraph. Likewise, while NavGraphBuilder.composable() adds composable destinations to the graph, here NavGraphBuilder.fragment() adds a fragment destination.

For more information on how to use the Kotlin DSL, see Build a graph with the NavGraphBuilder DSL.

XML

You can directly write the XML yourself. The following example mirrors and is equivalent to the two-screen example from the preceding section.

First, create a NavHostFragment. This serves as the navigation host which contains the actual navigation graph.

A minimal implementation of a NavHostFragment:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

</FrameLayout>

The NavHostFragment contains the attribute app:navGraph. Use this attribute to connect you navigation graph to the navigation host. The following is an example of how you might implement the graph:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph"
    app:startDestination="@id/profile">

    <fragment
        android:id="@+id/profile"
        android:name="com.example.ProfileFragment"
        android:label="Profile">

        <!-- Action to navigate from Profile to Friends List. -->
        <action
            android:id="@+id/action_profile_to_friendslist"
            app:destination="@id/friendslist" />
    </fragment>

    <fragment
        android:id="@+id/friendslist"
        android:name="com.example.FriendsListFragment"
        android:label="Friends List" />

    <!-- Add other fragment destinations similarly. -->
</navigation>

You use actions to define the connections between different destinations. In this example, the profile fragment contains an action that navigates to friendslist. For more information, see Use Navigation actions and fragments.

Editor

You can manage your app's navigation graph using the Navigation Editor in Android Studio. This is essentially a GUI you can use to create and edit your NavigationFragment XML, as seen in the preceding section.

For more information, see Navigation editor.

Nested graphs

You can also use nested graphs. This involves using a graph as a navigation destination. For more information, see Nested graphs.

Further Reading

For more core navigation concepts, see the following guides:

  • Overview: Make sure to read the general overview of the Navigation component.
  • Activity destinations: Examples of how to implement destinations that take the user to activities.
  • Dialog destinations: Examples of how to create destinations that take the user to a dialog.
  • Navigate to a destination: A detailed guide that covers how to navigate from one destination to another.
  • Nested graphs: An in-depth guide on how to nest one navigation graph within another.