Navigation 3 是一个从头开始为 Jetpack Compose 设计的导航库。本指南介绍了如何在 Wear OS 应用中实现 Navigation 3。
核心概念
NavKey:应用中目的地的类型安全的可序列化标识符。NavBackStack:表示导航历史记录的NavKey实例的可变列表。您可以直接从此列表中推送和弹出项。rememberNavBackStack:一种可组合项,用于在配置更改和进程终止后创建并保留返回堆栈。NavDisplay:用于观察返回堆栈并渲染活动屏幕的核心界面组件。EntryProvider:一种映射 DSL,用于将NavKey关联到其对应的实际@Composable界面。SwipeDismissableSceneStrategy:Wear 专用策略,可将您的屏幕封装在滑动关闭手势中,并处理内置的返回动画。
第 1 步:添加依赖项
向您的项目添加所需的 Navigation 3、Wear Compose 和序列化依赖项。
Groovy
dependencies { // Core Navigation 3 APIs implementation "androidx.navigation3:navigation3-runtime:1.2.0-alpha02" implementation "androidx.navigation3:navigation3-ui:1.2.0-alpha02" // Wear OS specific Navigation 3 integration implementation "androidx.wear.compose:compose-navigation3:1.6.1" // Kotlinx Serialization for type-safe routing implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0" }
Kotlin
dependencies { // Core Navigation 3 APIs implementation("androidx.navigation3:navigation3-runtime:1.2.0-alpha02") implementation("androidx.navigation3:navigation3-ui:1.2.0-alpha02") // Wear OS specific Navigation 3 integration implementation("androidx.wear.compose:compose-navigation3:1.6.1") // Kotlinx Serialization for type-safe routing implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0") }
第 2 步:定义目标平台 (NavKey)
界面定义为实现 NavKey 接口的强类型可序列化对象或数据类。
@Serializable sealed interface Screen : NavKey { @Serializable data object Home : Screen @Serializable data class Details(val itemId: String) : Screen }
第 3 步:设置 NavDisplay 和返回堆栈
在应用根目录中,初始化返回堆栈和 Wear OS 场景策略,然后将它们插入 NavDisplay。
// 1. Create the persistent back stack starting at the Home screen val backStack = rememberNavBackStack(Screen.Home) // 2. Initialize the Wear OS swipe-to-dismiss strategy val strategy = rememberSwipeDismissableSceneStrategy<NavKey>() // 3. Render the NavDisplay NavDisplay( backStack = backStack, sceneStrategies = listOf(strategy), entryProvider = entryProvider { // 4. Map keys to Composables entry<Screen.Home> { HomeScreen( onNavigateToDetails = { id -> backStack.add(Screen.Details(id)) } ) } entry<Screen.Details> { key -> DetailsScreen( itemId = key.itemId, onBack = { backStack.removeAt(backStack.lastIndex) } ) } } )
第 4 步:执行导航操作
由于返回堆栈只是一个自定义的 MutableList,因此导航非常简单。您可以直接对 backStack 实例执行操作:
- 向前导航:
backStack.add(Screen.Details("123")) - 返回:
backStack.removeLast()或backStack.removeLastOrNull() - 清除并重置:
backStack.clear(); backStack.add(Screen.Home)(或使用列表操作替换堆栈)。
第 5 步:(可选)将 ViewModel 的范围限定为目的地
默认情况下,ViewModel 的范围限定为 Activity。Navigation 3 提供了一个专用制品 (lifecycle-viewmodel-navigation3),用于将 ViewModel 安全地限定到返回堆栈上的 NavEntry。当目的地从返回堆栈中弹出时,ViewModel 会被清除。
添加依赖项:
implementation("androidx.lifecycle:lifecycle-viewmodel-navigation3:...")将 ViewModel 存储区装饰器添加到
NavDisplay的entryDecorators中。在提供自定义装饰器以保留 ComposerememberSaveable状态时,您还必须明确添加SaveableStateHolderNavEntryDecorator:NavDisplay( backStack = backStack, sceneStrategies = listOf(strategy), entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), rememberViewModelStoreNavEntryDecorator() ), entryProvider = entryProvider { entry<Screen.Home> { // Any viewModel() requested here will be scoped to this NavEntry val viewModel: HomeViewModel = viewModel() } } )