androidx.wear.compose.navigation

Classes

SwipeDismissableNavHostState

State for SwipeDismissableNavHost

WearNavigator

Navigator that navigates through Composables.

WearNavigator.Destination

NavDestination specific to WearNavigator

Top-level functions summary

Unit
@Composable
SwipeDismissableNavHost(
    navController: NavHostController,
    graph: NavGraph,
    modifier: Modifier,
    userSwipeEnabled: Boolean,
    state: SwipeDismissableNavHostState
)

Provides a place in the Compose hierarchy for self-contained navigation to occur, with backwards navigation provided by a swipe gesture.

Unit
@Composable
SwipeDismissableNavHost(
    navController: NavHostController,
    startDestination: String,
    modifier: Modifier,
    userSwipeEnabled: Boolean,
    state: SwipeDismissableNavHostState,
    route: String?,
    builder: NavGraphBuilder.() -> Unit
)

Provides a place in the Compose hierarchy for self-contained navigation to occur, with backwards navigation provided by a swipe gesture.

NavHostController

Creates a NavHostController that handles the adding of the WearNavigator from androidx.wear.compose.navigation.

SwipeDismissableNavHostState

Create a SwipeToDismissBoxState and remember it.

Extension functions summary

Unit
NavGraphBuilder.composable(
    route: String,
    arguments: List<NamedNavArgument>,
    deepLinks: List<NavDeepLink>,
    content: @Composable (NavBackStackEntry) -> Unit
)

Utility function for building Wear Compose navigation graphs.

State<NavBackStackEntry?>

Gets the current navigation back stack entry as a State.

Top-level functions

SwipeDismissableNavHost

@Composable
fun SwipeDismissableNavHost(
    navController: NavHostController,
    graph: NavGraph,
    modifier: Modifier = Modifier,
    userSwipeEnabled: Boolean = true,
    state: SwipeDismissableNavHostState = rememberSwipeDismissableNavHostState()
): Unit

Provides a place in the Compose hierarchy for self-contained navigation to occur, with backwards navigation provided by a swipe gesture.

Once this is called, any Composable within the given NavGraphBuilder can be navigated to from the provided navController.

The builder passed into this method is remembered. This means that for this NavHost, the contents of the builder cannot be changed.

During a swipe-to-dismiss gesture, the previous navigation level (if any) is shown in the background. BackgroundScrimColor and ContentScrimColor of it are taken from LocalSwipeToDismissBackgroundScrimColor and LocalSwipeToDismissContentScrimColor.

Below API level 35, content of the current navigation level is displayed within a BasicSwipeToDismissBox to detect swipe back gestures.

API level 35 onwards, SwipeDismissableNavHost listens to platform predictive back events for navigation, and BasicSwipeToDismissBox is not used for swipe gesture detection.

Example of a SwipeDismissableNavHost alternating between 2 screens:

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.wear.compose.material.Button
import androidx.wear.compose.material.Text
import androidx.wear.compose.navigation.SwipeDismissableNavHost
import androidx.wear.compose.navigation.composable
import androidx.wear.compose.navigation.rememberSwipeDismissableNavController

// Example of using a NavHost where each destination in the NavGraph has a unique name.
val navController = rememberSwipeDismissableNavController()
SwipeDismissableNavHost(navController = navController, startDestination = "off") {
    composable("off") {
        Column(
            modifier = Modifier.fillMaxSize(),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Button(onClick = { navController.navigate("on") }) { Text("On") }
        }
    }
    composable("on") {
        Column(
            modifier = Modifier.fillMaxSize(),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Button(onClick = { navController.navigate("off") }) { Text("Off") }
        }
    }
}

Example of a SwipeDismissableNavHost for which a destination has a named argument:

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.navigation.NavType
import androidx.navigation.navArgument
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
import androidx.wear.compose.material.CompactChip
import androidx.wear.compose.material.ListHeader
import androidx.wear.compose.material.Text
import androidx.wear.compose.navigation.SwipeDismissableNavHost
import androidx.wear.compose.navigation.composable
import androidx.wear.compose.navigation.rememberSwipeDismissableNavController

// Example of using a NavHost where we pass an argument to a destination in the NavGraph.
val navController = rememberSwipeDismissableNavController()
SwipeDismissableNavHost(navController = navController, startDestination = "list") {
    composable("list") {
        ScalingLazyColumn(
            modifier = Modifier.fillMaxSize(),
            contentPadding = PaddingValues(horizontal = 8.dp, vertical = 32.dp),
            verticalArrangement = Arrangement.Center,
        ) {
            item { ListHeader { Text("List Screen") } }
            items(5) { index ->
                CompactChip(
                    modifier = Modifier.padding(vertical = 4.dp),
                    onClick = { navController.navigate("detail/$index") },
                    label = {
                        Text(
                            text = "Item $index",
                            textAlign = TextAlign.Center,
                            modifier = Modifier.fillMaxSize()
                        )
                    }
                )
            }
        }
    }
    composable(
        route = "detail/{Id}",
        arguments = listOf(navArgument("Id") { type = NavType.IntType })
    ) { backStackEntry ->
        val itemId = backStackEntry.arguments?.getInt("Id") ?: 0
        Column(
            modifier = Modifier.fillMaxSize(),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            ListHeader { Text("Details Screen") }
            Text("Item $itemId")
        }
    }
}
Parameters
navController: NavHostController

NavHostController for this host

graph: NavGraph

Graph for this host

modifier: Modifier = Modifier

Modifier to be applied to the layout

userSwipeEnabled: Boolean = true

Boolean Whether swipe-to-dismiss gesture is enabled.

state: SwipeDismissableNavHostState = rememberSwipeDismissableNavHostState()

State containing information about ongoing swipe and animation. This parameter is unused API level 35 onwards, because the platform supports predictive back and SwipeDismissableNavHost uses platform gestures to detect the back gestures.

Throws
kotlin.IllegalArgumentException

if no WearNavigation.Destination is on the navigation backstack.

SwipeDismissableNavHost

@Composable
fun SwipeDismissableNavHost(
    navController: NavHostController,
    startDestination: String,
    modifier: Modifier = Modifier,
    userSwipeEnabled: Boolean = true,
    state: SwipeDismissableNavHostState = rememberSwipeDismissableNavHostState(),
    route: String? = null,
    builder: NavGraphBuilder.() -> Unit
): Unit

Provides a place in the Compose hierarchy for self-contained navigation to occur, with backwards navigation provided by a swipe gesture.

Once this is called, any Composable within the given NavGraphBuilder can be navigated to from the provided navController.

The builder passed into this method is remembered. This means that for this NavHost, the contents of the builder cannot be changed.

During a swipe-to-dismiss gesture, the previous navigation level (if any) is shown in the background. BackgroundScrimColor and ContentScrimColor of it are taken from LocalSwipeToDismissBackgroundScrimColor and LocalSwipeToDismissContentScrimColor.

Below API level 35, content of the current navigation level is displayed within a BasicSwipeToDismissBox to detect swipe back gestures.

API level 35 onwards, SwipeDismissableNavHost listens to platform predictive back events for navigation, and BasicSwipeToDismissBox is not used for swipe gesture detection.

Example of a SwipeDismissableNavHost alternating between 2 screens:

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.wear.compose.material.Button
import androidx.wear.compose.material.Text
import androidx.wear.compose.navigation.SwipeDismissableNavHost
import androidx.wear.compose.navigation.composable
import androidx.wear.compose.navigation.rememberSwipeDismissableNavController

// Example of using a NavHost where each destination in the NavGraph has a unique name.
val navController = rememberSwipeDismissableNavController()
SwipeDismissableNavHost(navController = navController, startDestination = "off") {
    composable("off") {
        Column(
            modifier = Modifier.fillMaxSize(),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Button(onClick = { navController.navigate("on") }) { Text("On") }
        }
    }
    composable("on") {
        Column(
            modifier = Modifier.fillMaxSize(),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Button(onClick = { navController.navigate("off") }) { Text("Off") }
        }
    }
}

Example of a SwipeDismissableNavHost for which a destination has a named argument:

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.navigation.NavType
import androidx.navigation.navArgument
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
import androidx.wear.compose.material.CompactChip
import androidx.wear.compose.material.ListHeader
import androidx.wear.compose.material.Text
import androidx.wear.compose.navigation.SwipeDismissableNavHost
import androidx.wear.compose.navigation.composable
import androidx.wear.compose.navigation.rememberSwipeDismissableNavController

// Example of using a NavHost where we pass an argument to a destination in the NavGraph.
val navController = rememberSwipeDismissableNavController()
SwipeDismissableNavHost(navController = navController, startDestination = "list") {
    composable("list") {
        ScalingLazyColumn(
            modifier = Modifier.fillMaxSize(),
            contentPadding = PaddingValues(horizontal = 8.dp, vertical = 32.dp),
            verticalArrangement = Arrangement.Center,
        ) {
            item { ListHeader { Text("List Screen") } }
            items(5) { index ->
                CompactChip(
                    modifier = Modifier.padding(vertical = 4.dp),
                    onClick = { navController.navigate("detail/$index") },
                    label = {
                        Text(
                            text = "Item $index",
                            textAlign = TextAlign.Center,
                            modifier = Modifier.fillMaxSize()
                        )
                    }
                )
            }
        }
    }
    composable(
        route = "detail/{Id}",
        arguments = listOf(navArgument("Id") { type = NavType.IntType })
    ) { backStackEntry ->
        val itemId = backStackEntry.arguments?.getInt("Id") ?: 0
        Column(
            modifier = Modifier.fillMaxSize(),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            ListHeader { Text("Details Screen") }
            Text("Item $itemId")
        }
    }
}
Parameters
navController: NavHostController

The navController for this host

startDestination: String

The route for the start destination

modifier: Modifier = Modifier

The modifier to be applied to the layout

userSwipeEnabled: Boolean = true

Boolean Whether swipe-to-dismiss gesture is enabled.

state: SwipeDismissableNavHostState = rememberSwipeDismissableNavHostState()

State containing information about ongoing swipe and animation. This parameter is unused API level 35 onwards, because the platform supports predictive back and SwipeDismissableNavHost uses platform gestures to detect the back gestures.

route: String? = null

The route for the graph

builder: NavGraphBuilder.() -> Unit

The builder used to construct the graph

rememberSwipeDismissableNavController

@Composable
fun rememberSwipeDismissableNavController(): NavHostController

Creates a NavHostController that handles the adding of the WearNavigator from androidx.wear.compose.navigation.

rememberSwipeDismissableNavHostState

@Composable
fun rememberSwipeDismissableNavHostState(
    swipeToDismissBoxState: SwipeToDismissBoxState = rememberSwipeToDismissBoxState()
): SwipeDismissableNavHostState

Create a SwipeToDismissBoxState and remember it.

Parameters
swipeToDismissBoxState: SwipeToDismissBoxState = rememberSwipeToDismissBoxState()

State for BasicSwipeToDismissBox, which is used to support the swipe-to-dismiss gesture in SwipeDismissableNavHost and can also be used to support edge-swiping, using edgeSwipeToDismiss. This parameter is unused after API 35, because the platform supports edge-swiping via predictive back gesture, and SwipeDismissableNavHost drops the use of BasicSwipeToDismissBox in favour of predictive back based navigation.

Extension functions

fun NavGraphBuilder.composable(
    route: String,
    arguments: List<NamedNavArgument> = emptyList(),
    deepLinks: List<NavDeepLink> = emptyList(),
    content: @Composable (NavBackStackEntry) -> Unit
): Unit

Utility function for building Wear Compose navigation graphs.

Adds the content composable to the NavGraphBuilder as a WearNavigator.Destination.

Parameters
route: String

route for the destination

arguments: List<NamedNavArgument> = emptyList()

list of arguments to associate with destination

deepLinks: List<NavDeepLink> = emptyList()

list of deep links to associate with the destinations

content: @Composable (NavBackStackEntry) -> Unit

composable for the destination

currentBackStackEntryAsState

@Composable
fun NavController.currentBackStackEntryAsState(): State<NavBackStackEntry?>

Gets the current navigation back stack entry as a State. When the given navController changes the back stack due to a NavController.navigate or NavController.popBackStack this will trigger a recompose and return the top entry on the back stack.

Returns
State<NavBackStackEntry?>

state of the current back stack entry