导航组件与 Android 操作系统协同工作,以在用户在您的应用中导航时维护 返回栈。在某些情况下,同时维护多个返回栈可能会有所帮助,用户可以在它们之间来回切换。例如,如果您的应用包含 底部导航 或 导航抽屉,则多个返回栈支持允许您的用户在应用中的流程之间自由切换,而不会丢失任何流程中的位置。
导航组件提供了支持多个返回栈的 API,方法是保存和恢复 导航图 中目标的状态。NavigationUI
类包含自动处理此操作的方法,但您也可以手动使用底层 API 来实现更自定义的实现。
使用 NavigationUI 自动实现支持
NavigationUI
类包含 API,这些 API 会在用户在菜单项之间移动时自动保存和恢复菜单项的状态。在以下情况下,这些 API 默认情况下实现多个返回栈支持
- 当您使用
setupWithNavController()
的适当重载将NavigationView
或BottomNavigationView
的实例与NavController
实例关联时,如 添加导航抽屉 或 底部导航 中所述。 - 当您使用
onNavDestinationSelected()
创建与NavController
实例托管的目标关联的 自定义导航菜单 UI 时。
这些 API 不需要任何其他代码更改即可实现多个返回栈支持,并且是您应用中支持多个返回栈的推荐方法。
使用底层 API 手动实现支持
如果 NavigationUI
提供的元素不能满足您的需求,您可以使用底层 API 通过导航组件提供的其他 API 表面之一保存和恢复返回栈。
导航 XML
在导航 XML 中,导航图中的 <action>
元素可以使用 app:popUpToSaveState
属性保存操作使用 app:popUpTo
弹出的任何目标的状态。它们还可以使用 app:restoreState
属性恢复 app:destination
属性中定义的目标的任何先前保存的状态。
您可以使用这些属性来支持多个返回栈。当导航操作需要将用户从一个返回栈移动到另一个返回栈时,请在相应的 <action>
元素中将 app:popUpToSaveState
和 app:restoreState
都设置为 true
。这样,操作会在保存当前返回栈状态的同时,还恢复目标返回栈的先前保存状态(如果存在)。
以下示例显示了一个使用这两个属性的操作
<action
android:id=”@+id/swap_stack”
app:destination=”@id/second_stack”
app:restoreState=”true”
app:popUpTo=”@id/first_stack_start_destination”
app:popUpToSaveState=”true” />
NavOptions
NavOptions
类允许您在使用 NavController
导航时传递特殊的导航选项以保存和恢复返回栈。无论您是使用 Kotlin DSL 还是使用 NavOptions.Builder
创建 NavOptions
实例,这都是正确的。
Kotlin
// Use the navigate() method that takes a navOptions DSL Builder navController.navigate(selectedBottomNavRoute) { launchSingleTop = true restoreState = true popUpTo(navController.graph.findStartDestination().id) { saveState = true } }
Java
NavOptions navOptions = new NavOptions.Builder() .setLaunchSingleTop(true) .setRestoreState(true) .setPopUpTo(NavGraph.findStartDestination(navController.getGraph()).getId(), false, // inclusive true) // saveState .build(); navController.navigate(selectedBottomNavId, null, navOptions);
要了解有关传递导航选项的更多信息,请参阅 以编程方式应用 NavOptions。
其他资源
要了解有关 Navigation 组件的多重返回栈支持的更多信息,请参阅以下其他资源
博文
- MAD Skills:导航多个返回栈(在 Medium 上)
- 导航:多个返回栈深度解析(在 Medium 上)
示例
- Now in Android 应用(在 GitHub 上)
- Jetnews(在 GitHub 上)
- Jetsnack(在 GitHub 上)