Nawigacja i stos tylny

NavController zawiera „stos tylny” zawierający miejsca docelowe, który odwiedził. Gdy użytkownik przechodzi do różnych ekranów w aplikacji, NavController dodaje miejsca docelowe do stosu tylnego oraz z nich usuwa miejsca docelowe.

Stos tylny to „ostatnie wejście, pierwsze wyjście”. do struktury danych. Dlatego NavController umieszcza produkty na górze stosów.

Podstawowe zachowanie

Oto podstawowe fakty, które warto wziąć pod uwagę, jeśli chodzi o zachowanie tylnej strony stos:

  • Pierwsze miejsce docelowe: gdy użytkownik otwiera aplikację, NavController przenosi pierwszy punkt docelowy na górę stosu wstecznego.
  • Przekazywanie do stosu: każde wywołanie NavController.navigate() przekazuje dane miejsce docelowe na górę stosu.
  • Wyświetlanie górnego miejsca docelowego: kliknięcie w górę lub Wstecz powoduje wywołanie funkcji NavController.navigateUp() i NavController.popBackStack() metod weryfikacji danych. Wyprzedzają z kolei najważniejsze miejsce docelowe. Zobacz Na stronie Zasady nawigacji znajdziesz więcej informacji o różnicach. między strzałkami w górę i Wstecz.

Cofnij

Metoda NavController.popBackStack() próbuje wypełnić bieżący miejsce docelowe poza stosem wstecznym i przejść do poprzedniego miejsca docelowego. Ten cofnie użytkownika o jeden krok w historii nawigacji. Zwraca wartość logiczna wskazująca, czy reklama wyświetliła się z powrotem do miejsca docelowego.

Powrót do określonego miejsca

Możesz też użyć usługi popBackStack(), aby wyznaczyć trasę do konkretnego miejsca docelowego. Do zrobienia użyj więc jednego z jego przeciążeń. Istnieją różne metody, które umożliwiają przekazywanie identyfikator, np. liczba całkowita id lub ciąg znaków route. Takie przeciążenia mogą użytkownika do miejsca docelowego powiązanego z danym identyfikatorem. Bardzo ważne jest, na stosie nad miejscem docelowym.

Te przeciążenia wymagają też wartości logicznej inclusive. Określa on, czy Funkcja NavController powinna również wycofywać określone miejsce docelowe ze stosu wstecznego. po dotarciu do tego miejsca.

Weźmy za przykład ten krótki fragment:

navController.popBackStack(R.id.destinationId, true)

W tym miejscu NavController wraca do miejsca docelowego z identyfikatorem całkowitą. destinationId Wartość argumentu inclusive wynosi true, więc NavController wybiera też miejsce docelowe ze stosu wstecznego.

Obsługa nieudanego wyskakującego okienka

Gdy popBackStack() zwraca wartość false, kolejne wywołanie funkcji NavController.getCurrentDestination() zwraca null. Oznacza to, że: i wypukł ostatni miejsce docelowe ze stosu. W takim przypadku użytkownik zobaczy tylko pusty ekran.

Może się tak zdarzyć w tych przypadkach:

  • popBackStack() nie wyskoczył(a) nic ze stosu.
  • popBackStack() wyprzedził(a) miejsce docelowe z tylnego stosu, a stos jest teraz puste.

Aby rozwiązać ten problem, musisz przejść na nowe miejsce docelowe lub zadzwonić pod numer finish() aby ją zakończyć. Oto przykład:

Kotlin

...

if (!navController.popBackStack()) {
    // Call finish() on your Activity
    finish()
}

kawa

...

if (!navController.popBackStack()) {
    // Call finish() on your Activity
    finish();
}

Wyskakujące okienko do miejsca docelowego

Aby usunąć miejsca docelowe ze stosu wstecznego podczas nawigacji z jednego miejsca docelowego do innej, dodaj argument popUpTo() do powiązanej funkcji navigate() . popUpTo() nakazuje bibliotece nawigacji usunięcie niektórych miejsc docelowych ze stosu tylnego w ramach wywołania funkcji navigate(). Wartość parametru to identyfikator miejsca docelowego na stosie wstecz. Identyfikatorem może być liczba całkowita id lub ciąg route.

Możesz dołączyć argument dla parametru inclusive o wartości true aby wskazać, że miejsce docelowe określone w popUpTo() również powinno wydzielić się ze stosu.

Aby zaimplementować tę funkcję automatycznie, przekaż popUpTo() do navigate() w ramach NavOptions z inclusive ustawionym na true. Działa to zarówno w funkcji Utwórz, Wyświetlenia.

Zapisz stan podczas wyświetlania wyskakującego okienka

Gdy korzystasz z funkcji popUpTo do nawigacji do miejsca docelowego, możesz opcjonalnie zapisać a także stany wszystkich miejsc docelowych. Dostępne opcje a następnie przywróć stos wsteczny i miejsca docelowe po przejściu do tego miejsca docelowego a później. Pozwala to zachować stan danego miejsca docelowego wielu tylnych stosów.

Aby zrobić to automatycznie, określ saveState = true podczas dodawania elementu popUpTo do opcje nawigacji.

Możesz też określić restoreState = true w opcjach nawigacji, aby automatycznie przywróci stos wsteczny i stan powiązany z miejsce docelowe.

Na przykład:

navController.navigate(
    route = route,
    navOptions =  navOptions {
        popUpTo<A>{ saveState = true }
        restoreState = true
    }
)

Aby włączyć zapisywanie i przywracanie stanu w pliku XML, zdefiniuj popUpToSaveState jako true i restoreState jako true w powiązanych uprawnieniach action.

Przykład w formacie XML

Oto przykład kodu popUpTo w formacie XML z użyciem działania:

<action
  android:id="@+id/action_a_to_b"
  app:destination="@id/b"
  app:popUpTo="@+id/a"
  app:popUpToInclusive="true"
  app:restoreState=”true”
  app:popUpToSaveState="true"/>

Przykład tworzenia wiadomości

Oto pełny przykład funkcji Compose:

@Composable
fun MyAppNavHost(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
    startDestination: Any = A
) {
    NavHost(
        modifier = modifier,
        navController = navController,
        startDestination = startDestination
    ) {
        composable<A> {
            DestinationA(
                onNavigateToB = {
                // Pop everything up to, and including, the A destination off
                // the back stack, saving the back stack and the state of its
                // destinations.
                // Then restore any previous back stack state associated with
                // the B destination.
                // Finally navigate to the B destination.
                    navController.navigate(route = B) {
                        popUpTo<A> {
                            inclusive = true
                            saveState = true
                        }
                        restoreState = true
                    }
                },
            )
        }
        composable<B> { DestinationB(/* ... */) }
    }
}

@Composable
fun DestinationA(onNavigateToB: () -> Unit) {
    Button(onClick = onNavigateToB) {
        Text("Go to A")
    }
}

Bardziej szczegółowo możesz zmienić sposób, w jaki wywołujesz NavController.navigate() w w następujący sposób:

// Pop everything up to the destination_a destination off the back stack before
// navigating to the "destination_b" destination
navController.navigate("destination_b") {
    popUpTo("destination_a")
}

// Pop everything up to and including the "destination_a" destination off
// the back stack before navigating to the "destination_b" destination
navController.navigate("destination_b") {
    popUpTo("destination_a") { inclusive = true }
}

// Navigate to the "search” destination only if we’re not already on
// the "search" destination, avoiding multiple copies on the top of the
// back stack
navController.navigate("search") {
    launchSingleTop = true
}

Ogólne informacje o przekazywaniu opcji do NavController.navigate() znajdziesz w zapoznaj się z przewodnikiem po opcjach nawigacji.

Pop za pomocą działań

Podczas nawigowania za pomocą działania możesz opcjonalnie wskazać dodatkowe miejsca docelowe z tyłu. Jeśli na przykład w aplikacji występuje początkowy proces logowania, po użytkownik jest zalogowany, należy wyłączyć wszystkie miejsca docelowe związane z logowaniem. aby przycisk Wstecz nie przenosił użytkowników z powrotem do logowania przepływu danych.

Materiały dodatkowe

Więcej informacji znajdziesz na tych stronach:

  • Nawigacja po kołach: dowiedz się, jak uniknąć nadmiernego nawiedzenia oczu. w przypadkach, gdy przepływy nawigacji są kołowe.
  • Miejsca docelowe okien: przeczytaj, jak wprowadzają miejsca docelowe okien na wyjątkowe kwestie dotyczące zarządzania stosem backendu.