Круговая навигация

Яркий пример того, когда вам нужно вернуться к месту назначения, — это круговая навигация. В этом документе описывается этот вариант использования.

Сценарий

Представьте, что у вашего приложения есть три пункта назначения: A, B и C. В нем также есть действия, ведущие из A в B, из B в C и из C обратно в A. Соответствующий граф навигации выглядит следующим образом:

демонстрация круговой навигации
Рисунок 1. Круговой навигационный граф с тремя пунктами назначения: A, B и C.

С каждым действием навигации NavController добавляет новый пункт назначения в задний стек. Таким образом, неоднократное перемещение по потоку на диаграмме приведет к тому, что ваш задний стек будет содержать несколько наборов каждого пункта назначения: A, B, C, A, B, C, A, B, C.

Решение

Чтобы избежать повторения в обратном стеке, укажите popUpTo() и inclusive в вызове NavController.navigate() или в действии навигации.

Рассмотрим случай, когда после достижения пункта назначения C обратный стек содержит по одному экземпляру каждого пункта назначения: A, B, C. Вам необходимо убедиться, что вы определили popUpTo() и inclusive в действие или вызов navigate() , который принимает пользователь из пункта назначения C в пункт назначения A.

В этом случае, когда пользователь переходит из пункта назначения C обратно в пункт назначения A, NavController также появляется в пункте A. Это означает, что он удаляет B и C из стека. При использовании inclusive = true он также извлекает первую A, эффективно очищая стек.

Составьте реализацию

Ниже приведена реализация решения для циклического popUpTo() в Compose:

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

Реализация представлений

Ниже приведена реализация решения для циклического 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>