Das NavController
enthält einen „Back-Stack“ mit den Zielen, die der Nutzer besucht hat. Wenn der Nutzer zu Bildschirmen in Ihrer App navigiert, werden vom NavController
Ziele zum Back-Stack hinzugefügt und daraus entfernt.
Als Stack wird der Back-Stack als „Last In, First Out“-Datenstruktur bezeichnet.
Der NavController
verschiebt Elemente daher zum oberen Rand des Stapels und entfernt sie vom Anfang des Stapels.
Grundlegende Funktionsweise
Dies sind die wichtigsten Fakten zum Verhalten des Backstacks:
- Erstes Ziel:Wenn der Nutzer die App öffnet, verschiebt
NavController
das erste Ziel nach oben im Back-Stack. - Per Push in den Stack übertragen: Bei jedem
NavController.navigate()
-Aufruf wird das angegebene Ziel an den Anfang des Stacks verschoben. - Top-Ziel einblenden: Wenn Sie auf Nach oben oder Zurück tippen, werden die Methoden
NavController.navigateUp()
bzw.NavController.popBackStack()
aufgerufen. Das oberste Ziel wird vom Stapel gelöst. Weitere Informationen zum Unterschied zwischen den beiden Seiten Nach oben und Zurück finden Sie auf der Seite Grundlagen der Navigation.
Zurück
Mit der Methode NavController.popBackStack()
wird versucht, das aktuelle Ziel aus dem Back-Stack zu entfernen und zum vorherigen Ziel zu wechseln. Dadurch wird der Nutzer im Navigationsverlauf einen Schritt zurückversetzt. Sie gibt einen booleschen Wert zurück, der angibt, ob die Verbindung erfolgreich an das Ziel übergeben wurde.
Zu einem bestimmten Ziel zurückkehren
Sie können auch popBackStack()
verwenden, um zu einem bestimmten Ziel zu navigieren. Verwenden Sie dazu eine der Überlastungen. Es gibt mehrere Möglichkeiten, eine ID zu übergeben, z. B. eine Ganzzahl id
oder einen String route
. Diese Überlastungen bringen den Nutzer zu dem Ziel, das der angegebenen Kennung zugeordnet ist. Entscheidend ist, dass sie alle Elemente auf dem Stack über dem Ziel platzieren.
Für diese Überlasten wird auch ein boolescher Wert vom Typ inclusive
verwendet. Damit wird festgelegt, ob das angegebene Ziel auch aus dem Back-Stack entfernt werden soll, nachdem das NavController
aufgerufen wurde.
Sehen Sie sich zum Beispiel dieses kurze Snippet an:
navController.popBackStack(R.id.destinationId, true)
Hier wird NavController
wieder zum Ziel mit der Ganzzahl-ID destinationId
zurückgegeben. Da der Wert des Arguments inclusive
true
ist, entfernt der NavController
auch das angegebene Ziel aus dem Back-Stack.
Umgang mit einem fehlgeschlagenen Pop-back
Wenn popBackStack()
den Wert false
zurückgibt, wird bei einem nachfolgenden Aufruf von NavController.getCurrentDestination()
null
zurückgegeben. Das bedeutet, dass die App das letzte Ziel
aus dem Back Stack entfernt hat. In diesem Fall sieht der Nutzer
nur einen leeren Bildschirm.
Das kann in den folgenden Fällen vorkommen:
popBackStack()
hat nichts aus dem Stapel gezogen.popBackStack()
hat ein Ziel aus dem Back Stack entfernt und der Stack ist jetzt leer.
Um dieses Problem zu beheben, müssen Sie ein neues Ziel aufrufen oder finish()
für Ihre Aktivität aufrufen, um sie zu beenden. Das folgende Snippet veranschaulicht dies:
Kotlin
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish()
}
Java
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish();
}
Zu einem Ziel wechseln
Wenn Sie bei der Navigation von einem Ziel zu einem anderen Ziele aus dem Back-Stack entfernen möchten, fügen Sie dem zugehörigen navigate()
-Funktionsaufruf ein popUpTo()
-Argument hinzu. popUpTo()
weist die Navigationsbibliothek an, im Rahmen des navigate()
-Aufrufs einige Ziele aus dem Back Stack zu entfernen. Der Parameterwert ist die Kennung eines Ziels auf dem Back-Stack. Die Kennzeichnung kann eine Ganzzahl id
oder ein String des Typs route
sein.
Sie können ein Argument für den Parameter inclusive
mit dem Wert true
angeben, um anzugeben, dass das in popUpTo()
angegebene Ziel auch aus dem Back-Stack herauskommen soll.
Wenn Sie dies programmatisch implementieren möchten, übergeben Sie popUpTo()
als Teil von NavOptions
an navigate()
, wobei inclusive
auf true
gesetzt ist. Dies funktioniert sowohl in der
Schreibfunktion als auch in der Ansicht.
Status beim Pop-up speichern
Wenn Sie mit popUpTo
zu einem Ziel navigieren, können Sie optional die Status aller Ziele speichern, die aus dem Back-Stack herausgenommen werden.
Definieren Sie zum Aktivieren dieser Option popUpToSaveState
als true
in der zugehörigen action
oder rufen Sie NavController.navigate()
auf.
Wenn Sie zu einem Ziel gehen, können Sie restoreSaveState
auch als true
definieren, um automatisch den Status wiederherzustellen, der dem Ziel in der destination
-Property zugeordnet ist.
Beispiel für XML
Hier ist ein Beispiel für popUpTo
in XML mit einer Aktion:
<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"/>
Beispiele für die Erstellung
Im Folgenden finden Sie ein vollständiges Beispiel dafür in der Funktion „Compose“:
@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")
}
}
Sie können die Aufruffunktion von NavController.navigate()
auch folgendermaßen ändern:
// 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
}
Allgemeine Informationen zum Übergeben von Optionen an NavController.navigate()
finden Sie im Leitfaden zur Navigation mit Optionen.
Pop mit Aktionen
Wenn Sie mithilfe einer Aktion navigieren, können Sie optional zusätzliche Ziele aus dem Back-Stack entfernen. Wenn Ihre Anwendung beispielsweise einen anfänglichen Anmeldevorgang hat, sollten Sie nach der Anmeldung eines Nutzers alle anmeldungsbezogenen Ziele aus dem Back-Stack entfernen, damit die Schaltfläche „Zurück“ die Nutzer nicht zurück zum Anmeldevorgang führt.
Zusätzliche Lesematerialien
Weitere Informationen finden Sie auf den folgenden Seiten:
- Kreisförmige Navigation: Hier erfahren Sie, wie Sie einen überfüllten Backstack in Fällen mit kreisförmigen Navigationsflüssen vermeiden können.
- Dialogziele: Lesen Sie, wie Dialogziele besondere Überlegungen bei der Verwaltung Ihres Back Stacks beinhalten.