借助 Navigation Compose API,您可以在 在 Compose 应用中利用 Jetpack Navigation 组件, 基础架构和功能。
本页介绍了如何从基于 fragment 的 Jetpack Navigation 迁移到 Navigation Compose,是基于 View 的界面向 Jetpack 大规模迁移的一部分 写邮件。
迁移先决条件
当您能够替换掉所有之前使用的 具有相应屏幕可组合项的 fragment。屏幕可组合项可以包含 混合使用 Compose 和 View 内容,但所有导航目的地都必须 可组合项来启用 Navigation Compose 迁移。在此之前,您应该 继续在互操作性 View 中使用基于 Fragment 的 Navigation 组件 Compose 代码库。如需了解详情,请参阅导航互操作性文档 信息。
在纯 Compose 应用中使用 Navigation Compose 不是前提条件。您可以 继续使用 基于 Fragment 的导航组件,前提是您保持 用于托管可组合项内容的 fragment。
迁移步骤
无论您是遵循我们推荐的迁移策略,还是采取 或者使用另一种方法,此时所有导航目的地 screen 可组合项,其中 fragment 仅充当可组合容器。目前 您可以迁移到 Navigation Compose。
如果您的应用已遵循 UDF 设计模式和我们的指南 架构,迁移到 Jetpack Compose 和 Navigation Compose 不应 需要对应用的其他层(界面层除外)进行重大重构。
如需迁移到 Navigation Compose,请按以下步骤操作:
- 将 Navigation Compose 依赖项添加到您的应用。
创建一个
App-level
可组合项,并将其添加到Activity
中作为 Compose 入口点,替换了 View 布局的设置:class SampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample) setContent { SampleApp(/* ... */) } } }
为每个导航目的地创建类型。将
data object
用于 不需要任何数据且data class
或class
需要数据的目的地。@Serializable data object First @Serializable data class Second(val id: String) @Serializable data object Third
在需要所有可组合项的位置设置
NavController
以便对其进行引用(这通常在App
内) 可组合项)。此方法遵循状态提升的原则 并且允许您使用NavController
作为 在可组合屏幕之间导航并维护返回堆栈:@Composable fun SampleApp() { val navController = rememberNavController() // ... }
在
App
可组合项内创建应用的NavHost
,并将navController
:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
添加
composable
目的地以构建导航图。如果每个 屏幕之前已迁移到 Compose,此步骤仅包括 将这些屏幕可组合项从 fragment 提取到composable
目的地:class FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { // FirstScreen(...) EXTRACT FROM HERE } } } } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen(/* ... */) // EXTRACT TO HERE } composable<Second> { SecondScreen(/* ... */) } // ... } }
如果您遵循了设计 Compose 界面架构中的指南, 具体而言,应如何将
ViewModel
和导航事件传递给 可组合项,下一步是更改向可组合项提供ViewModel
的方式 每个 screen 可组合项。您通常可以使用 Hilt 注入及其集成 通过hiltViewModel
使用 Compose 和 Navigation:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
将所有
findNavController()
导航调用替换为navController
并将其作为导航事件传递给每个可组合屏幕, 而不是传递整个navController
。此方法遵循了将可组合函数中的事件公开给调用方的最佳实践,并将navController
保持为单一可信来源。可通过创建路线实例将数据传递到目的地 类。然后,您可以直接获取 从目的地的返回堆栈条目或从
ViewModel
使用SavedStateHandle.toRoute()
。@Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen( onButtonClick = { // findNavController().navigate(firstScreenToSecondScreenAction) navController.navigate(Second(id = "ABC")) } ) } composable<Second> { backStackEntry -> val secondRoute = backStackEntry.toRoute<Second>() SecondScreen( id = secondRoute.id, onIconClick = { // findNavController().navigate(secondScreenToThirdScreenAction) navController.navigate(Third) } ) } // ... } }
移除所有 Fragment、相关的 XML 布局、不必要的导航和其他 过时的 fragment 和 Jetpack Navigation 依赖项。
您可以在 设置文档。
常见用例
无论您使用哪个导航组件,导航组件的 导航应用。
迁移的常见用例包括:
有关这些用例的更多详细信息,请参见使用 写邮件。
在导航时检索复杂数据
我们强烈建议您在导航时不要传递复杂的数据对象。 而应传递最少量的必要信息,例如唯一标识符或 ID 的其他形式的 ID,作为执行导航操作时的参数。您应该 将复杂对象作为数据存储在单一可信来源中,例如 层。有关详情,请参阅 导航。
如果您的 fragment 将复杂的对象作为参数传递,请考虑重构 以便从代码中存储和提取这些对象 数据层如需了解更多详情,请参阅 Now in Android 代码库 示例。
限制
本部分介绍 Navigation Compose 的当前限制。
逐步迁移到 Navigation Compose
目前,您无法在使用 Fragment 的同时,使用 Navigation Compose 目标。如需开始使用 Navigation Compose,您的所有 目的地必须是可组合项。您可以在 问题跟踪器。
过渡动画
从 Navigation 2.7.0-alpha01 开始,支持设置自定义
之前从“AnimatedNavHost
”改为现在
NavHost
直接支持。请仔细阅读以下内容的版本说明:
。
了解详情
如需详细了解如何迁移到 Navigation Compose,请参阅以下内容 资源:
- Navigation Compose Codelab:了解 Navigation Compose 的基础知识 通过实操 Codelab 学习。
- Now in Android 代码库:功能齐全的 Android 应用 完全使用 Kotlin 和 Jetpack Compose 构建而成,遵循 Android 设计理念 和开发最佳实践,并且包含 Navigation Compose。
- 将 Sunflower 迁移到 Jetpack Compose: 记录了 Sunflower 示例应用从 View 迁移到 Compose,还包括迁移到 Navigation Compose。
- 适用于所有屏幕的 Jetnews:记录 重构和迁移 Jetnews 示例,以支持 Jetpack Compose 和 Navigation Compose。
为您推荐
- 注意:当 JavaScript 处于关闭状态时,系统会显示链接文字
- 使用 Compose 进行导航
- Compose 和其他库
- 其他注意事项