NavController
zawiera „stos wsteczny”, który zawiera miejsca docelowe odwiedzonych przez użytkownika. Gdy użytkownik przechodzi między ekranami w aplikacji, NavController
dodaje miejsca docelowe do stosu wstecznego oraz je z niego usuwa.
W stosunku do stosu wstecznego struktura danych typu „ostatnie wejście, pierwsze wyjście”.
W ten sposób NavController
przenosi elementy do i wyskakuje z góry stosu.
Podstawowe działanie
Oto najważniejsze fakty dotyczące działania stosu wstecznego, które musisz wziąć pod uwagę:
- Pierwsze miejsce docelowe: gdy użytkownik otwiera aplikację,
NavController
przenosi pierwsze miejsce docelowe na górę stosu wstecznego. - Przekazywanie na stos: każde wywołanie
NavController.navigate()
przesuwa dane miejsce docelowe na szczyt stosu. - Miejsce docelowe u góry strony: kliknięcie W górę lub Wstecz wywołuje odpowiednio metody
NavController.navigateUp()
iNavController.popBackStack()
. Usuwają z grupy pierwsze miejsce docelowe. Na stronie Zasady nawigacji znajdziesz więcej informacji o różnicy między przyciskami góra i wstecz.
Odpręż się
Metoda NavController.popBackStack()
próbuje usunąć bieżące miejsce docelowe z stosu wstecznego i przejść do poprzedniego miejsca docelowego. Spowoduje to cofnięcie użytkownika o jeden krok w historii nawigacji. Zwraca wartość logiczną wskazującą, czy wiadomość powróciła do miejsca docelowego.
Wróć do konkretnego miejsca docelowego
Możesz też użyć aplikacji popBackStack()
, by przejść do konkretnego miejsca docelowego. Aby to zrobić, wykorzystaj jedno z jego przeciążeń. Jest kilka funkcji, które umożliwiają przekazywanie
identyfikatora, np. liczba całkowita id
lub ciąg znaków route
. Przeciążenia te kierują użytkownika do miejsca docelowego powiązanego z danym identyfikatorem. Co ważne, umieszcza wszystko w stosie nad tym miejscem docelowym.
Te przeciążenia również przyjmują wartość logiczną inclusive
. Określa, czy po przejściu do określonego miejsca docelowego NavController
powinno też usunąć określone miejsce docelowe ze stosu.
Weźmy na przykład ten krótki fragment kodu:
navController.popBackStack(R.id.destinationId, true)
NavController
wraca do miejsca docelowego z identyfikatorem liczby całkowitej destinationId
. Wartość argumentu inclusive
to true
, więc NavController
pobiera też dane miejsce docelowe ze stosu wstecznego.
Obsługa nieudanego okienka wyskakującego
Gdy popBackStack()
zwraca wartość false
, kolejne wywołanie metody NavController.getCurrentDestination()
zwraca wartość null
. Oznacza to, że aplikacja usunęła ostatnie miejsce docelowe ze stosu. W takim przypadku
użytkownik widzi tylko pusty ekran.
Może się tak zdarzyć w tych przypadkach:
popBackStack()
nie wyskoczył(a) ze stosu.popBackStack()
usunął miejsce docelowe ze stosu wstecznego i stos jest teraz pusty.
Aby rozwiązać ten problem, musisz przejść do nowego miejsca docelowego lub wywołać funkcję finish()
w aktywności, aby ją zakończyć. Można to zademonstrować za pomocą tego fragmentu kodu:
Kotlin
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish()
}
kawa
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish();
}
Zbliż się do miejsca docelowego
Aby usunąć miejsca docelowe ze stosu wstecznego podczas przechodzenia z jednego miejsca docelowego do innego, dodaj argument popUpTo()
do powiązanego wywołania funkcji navigate()
. popUpTo()
nakazuje bibliotece Nawigacji usunięcie niektórych miejsc docelowych ze stosu wstecznego w ramach wywołania navigate()
. Wartość parametru to identyfikator miejsca docelowego na stosie wstecznym. Identyfikator może być liczbą całkowitą id
lub ciągiem route
.
Możesz dołączyć argument dla parametru inclusive
o wartości true
, aby wskazać, że miejsce docelowe podane w zasadzie popUpTo()
też powinno zostać usunięte ze stosu.
Aby wdrożyć tę funkcję automatycznie, przekaż popUpTo()
do navigate()
w ramach NavOptions
z inclusive
ustawionym na true
. Działa to zarówno
w tworzeniu, jak i w widokach danych.
Zapisz stan po wyświetleniu reklamy
Gdy do nawigacji do miejsca docelowego używasz polecenia popUpTo
, możesz opcjonalnie zapisać stany wszystkich miejsc docelowych, które zostały usunięte ze stosu wstecznego.
Aby włączyć tę opcję, określ popUpToSaveState
jako true
w powiązanych action
lub wywołaj NavController.navigate()
.
Gdy jedziesz do miejsca docelowego, możesz też określić restoreSaveState
jako true
, aby automatycznie przywrócić stan powiązany z tym miejscem w usłudze destination
.
Przykład w formacie XML
Oto przykład kodu popUpTo
w pliku XML, w którym użyto 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łady tworzenia wiadomości
Poniżej znajdziesz pełny przykład podobnej funkcji w sekcji Utwórz:
@Composable
fun MyAppNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
startDestination: String = "destination_a"
) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = startDestination
) {
composable("destination_a") {
DestinationA(
onNavigateToB = {
// 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") {
inclusive = true
saveState = true
}
}
},
)
}
composable("destination_b") { DestinationB(/* ... */) }
}
}
@ Composable
fun DestinationA(onNavigateToB: () -> Unit) {
Button(onClick = onNavigateToB) {
Text("Go to A")
}
}
Bardziej szczegółowo możesz zmienić sposób wywoływania funkcji NavController.navigate()
na te sposoby:
// 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 przewodniku po opcjach.
Przebijaj za pomocą działań
Podczas nawigacji za pomocą działania możesz opcjonalnie wydzielić dodatkowe miejsca docelowe ze stosu wstecznego. Jeśli na przykład w aplikacji następuje początkowy proces logowania, to po zalogowaniu się użytkownika należy usunąć ze stosu wstecznego wszystkie miejsca docelowe związane z logowaniem, aby przycisk Wstecz nie kierował użytkowników z powrotem do procesu logowania.
Materiały dodatkowe
Więcej informacji znajdziesz na tych stronach:
- Nawigacja kołowa: dowiedz się, jak uniknąć nadmiernego nakładania się tyłu w przypadkach, gdy przepływy nawigacji mają charakter cykliczny.
- Miejsca docelowe okien: dowiedz się, jak miejsca docelowe okien wprowadzają specjalne zasady zarządzania stosem wstecznym.