循环导航

您需要返回到目标位置的一个清晰示例是当您的导航是循环时。本文档概述了该用例。

场景

假设您的应用有三个目标位置:A、B 和 C。它还有一些操作,可以从 A 导航到 B,从 B 导航到 C,从 C 返回到 A。相应的导航图如下所示

a demonstration of circular navigation
图 1. 一个包含三个目标位置(A、B 和 C)的循环导航图。

在每次导航操作中,NavController 将新目标位置添加到返回堆栈。因此,反复遍历图中的流程会导致您的返回堆栈包含每个目标位置的多个集合:A、B、C、A、B、C、A、B、C。

解决方案

为了避免在返回堆栈中重复,请在对 NavController.navigate() 的调用或导航操作中指定 popUpTo()inclusive

考虑这样一种情况,在到达目标位置 C 后,返回堆栈包含每个目标位置的一个实例:A、B、C。您需要确保已在将用户从目标位置 C 导航到目标位置 A 的操作或对 navigate() 的调用中定义了 popUpTo()inclusive

在这种情况下,当用户从目标位置 C 返回到目标位置 A 时,NavController 也会弹出到 A。这意味着它会从堆栈中删除 B 和 C。使用 inclusive = true,它还会弹出第一个 A,从而有效地清除堆栈。

Compose 实现

以下是 Compose 中循环 popUpTo() 解决方案的实现

// When creating your `NavGraph` in your `NavHost`.
composable("c") {
    DestinationC(
        onNavigateToA = {
          navController.navigate("a") {
            popUpTo("a") {
              inclusive = true
            }
          }
        },
    )
}

视图实现

以下是 Views 中循环 popUpTo 解决方案的实现

<fragment
    android:id="@+id/c"
    android:name="com.example.myapplication.C"
    android:label="fragment_c"
    tools:layout="@layout/fragment_c">

    <action
        android:id="@+id/action_c_to_a"
        app:destination="@id/a"
        app:popUpTo="@+id/a"
        app:popUpToInclusive="true"/>
</fragment>