Navigation 组件可与 Android 操作系统配合使用,以在用户在您的应用中导航时维护返回堆栈。在某些情况下,同时维护多个返回堆栈可能很有帮助,用户可以在这些返回堆栈之间来回移动。例如,如果您的应用包含底部导航栏或抽屉式导航栏,支持多个返回堆栈可让您的用户在各个流程之间自由切换,同时不会在任何流程中丢失所处的位置。
Navigation 组件提供了一些 API,这些 API 会在您的导航图中保存和恢复目的地状态,从而支持多个返回堆栈。NavigationUI
类包含自动实现这种情况的方法,但您也可以手动使用底层 API 来获得自定义程度更高的实现。
使用 NavigationUI 自动实现多个返回堆栈支持
NavigationUI
类包括一些 API,当用户在菜单项之间切换时,这些 API 会自动保存和恢复菜单项的状态。在以下情况下,这些 API 会默认实现多个返回堆栈支持:
- 当您使用
setupWithNavController()
的相应重载将NavigationView
或BottomNavigationView
的实例与NavController
实例相关联时(如添加抽屉式导航栏或底部导航栏中所述)。 - 当您使用
onNavDestinationSelected()
创建自定义导航菜单界面,且该界面与NavController
实例托管的目的地相关联时。
您无需进一步更改代码即可使用这些 API 来实现多个返回堆栈支持,因此建议您在应用中使用此方法支持多个返回堆栈。
使用底层 API 手动实现多个返回堆栈支持
如果 NavigationUI
提供的元素不满足您的要求,您可以通过 Navigation 组件提供的其他 API surface 使用底层 API 来保存和恢复返回堆栈。
导航 XML
在 Navigation 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 技巧:Navigation 多个返回堆栈(Medium 博文)
- Navigation:多个返回堆栈深入分析(Medium 博文)
示例
- GitHub 上的 Now in Android 应用示例
- GitHub 上的 Jetnews 示例
- GitHub 上的 Jetsnack 示例