Navigation with Compose for Wear OS

The Navigation component in Android Jetpack provides support for Jetpack Compose applications. You can navigate between composables while taking advantage of the Navigation component’s infrastructure and features.

This page describes the differences with Jetpack Navigation on Compose for Wear OS.

Setup

Use the following dependency in your app module’s build.gradle file:

Kotlin

dependencies {
    def wear_compose_version = "1.4.0"
    implementation "androidx.wear.compose:compose-navigation:$wear_compose_version"
}

This is used instead of the androidx.navigation:navigation-compose artifact because it provides alternative implementations specific to Wear OS.

Create a navigation controller, host and graph

Navigating with Compose for Wear OS requires the same three components needed on non-Wear OS apps: the navigation controller, host and graph.

Use rememberSwipeDismissableNavController() to create an instance of WearNavigator, an implementation of NavController suitable for Wear OS applications:

Kotlin

val navController = rememberSwipeDismissableNavController()

The NavController is the primary API used to navigate in Compose applications. It controls navigating between composables in the navigation host which, on Wear OS, is SwipeDismissableNavHost.

Kotlin

val navController = rememberSwipeDismissableNavController()
SwipeDismissableNavHost(
    navController = navController,
    startDestination = "message_list"
) {
    // TODO: build navigation graph
}

Like the NavHost composable, it takes a reference to the navigation controller, the route for the start destination, and the builder for the navigation graph which is shown here as a trailing lambda.

The start destination must be provided in the navigation graph builder, along with all other destinations that should be navigable with the navigation controller.

In your Wear OS app, declare SwipeDismissableNavHost as a content of the Scaffold to support top-level components like time, scroll/position indicator, and page indicator. Use a Horologist AppScaffold object above the SwipeDismissableNavHost and the Horologist ScreenScaffold at the screen level to add a TimeText object to the screen by default and to make sure it animates correctly when navigating between screens. Additionally, ScreenScaffold adds a PositionIndicator for scrollable content.

AppScaffold {
    val navController = rememberSwipeDismissableNavController()
    SwipeDismissableNavHost(
        navController = navController,
        startDestination = "message_list"
    ) {
        composable("message_list") {
            MessageList(onMessageClick = { id ->
                navController.navigate("message_detail/$id")
            })
        }
        composable("message_detail/{id}") {
            MessageDetail(id = it.arguments?.getString("id")!!)
        }
    }
}
// ...
// .. Screen level content goes here
val scrollState = rememberScrollState()

ScreenScaffold(scrollState = scrollState) {
    // Screen content goes here

To learn more about Jetpack Navigation, see Navigating with Compose or take the Jetpack Compose Navigation code lab.