NavController
contiene uno "stack back" contenente le destinazioni visitate
dall'utente. Mentre l'utente accede alle schermate dell'app, NavController
aggiunge e rimuove le destinazioni da e verso lo stack di backup.
In quanto stack, lo stack di back è una struttura di dati "l'ultimo accesso, il primo all'uscita".
Di conseguenza, l'elemento NavController
esegue il push di elementi all'interno dello stack e lo mostra a sua volta dalla parte superiore.
Comportamento di base
Di seguito sono riportati gli aspetti principali da considerare in merito al comportamento dello stack posteriore:
- Prima destinazione: quando l'utente apre l'app,
NavController
invia la prima destinazione alla parte superiore dello stack posteriore. - Push allo stack: ogni chiamata
NavController.navigate()
esegue il push della destinazione specificata in cima allo stack. - Per attivare la destinazione principale: se tocchi Su o Indietro vengono richiamati rispettivamente i metodi
NavController.navigateUp()
eNavController.popBackStack()
. Escono dalla pila la destinazione principale. Consulta la pagina Principi di navigazione per ulteriori informazioni sulla differenza tra Freccia su e Indietro.
Torna indietro
Il metodo NavController.popBackStack()
tenta di estrarre la destinazione
attuale dallo stack posteriore e di passare a quella precedente. In questo modo, l'utente può tornare indietro di un passaggio nella cronologia di navigazione. Restituisce
un valore booleano che indica se è tornato alla destinazione.
Torna a una destinazione specifica
Puoi anche utilizzare popBackStack()
per raggiungere una determinata destinazione. Per farlo, utilizza uno dei suoi sovraccarichi. Ce ne sono diversi che ti consentono di passare
un identificatore, come un numero intero id
o una stringa route
. Questi sovraccarichi portano l'utente alla destinazione associata all'identificatore specificato. Fondamentalmente, mettono tutto nello stack sopra la destinazione.
Questi sovraccarichi utilizzano anche un valore booleano inclusive
. Stabilisce se
NavController
deve anche estrarre la destinazione specificata dallo stack di riserva
dopo aver eseguito l'accesso.
Come esempio, considera questo breve snippet:
navController.popBackStack(R.id.destinationId, true)
Qui il campo NavController
torna alla destinazione con l'ID numero intero destinationId
. Poiché il valore dell'argomento inclusive
è true
, NavController
fa emergere anche la destinazione specificata dallo stack back.
Gestire un popback non riuscito
Quando popBackStack()
restituisce false
, una chiamata successiva a NavController.getCurrentDestination()
restituisce null
. Questo significa che l'app ha
scaricato l'ultima destinazione dallo stack di riserva. In questo caso, l'utente vede
solo una schermata vuota.
Ciò può verificarsi nei seguenti casi:
popBackStack()
non ha saltato nulla dall'elenco filtri.popBackStack()
ha rimosso una destinazione dallo stack posteriore e lo stack è ora vuoto.
Per risolvere il problema, devi accedere a una nuova destinazione o chiamare finish()
sulla tua attività per terminarla. Lo snippet riportato di seguito lo dimostra:
Kotlin
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish()
}
java
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish();
}
Vai a una destinazione
Per rimuovere le destinazioni dallo stack posteriore durante il passaggio da una destinazione a un'altra, aggiungi un argomento popUpTo()
alla chiamata di funzione navigate()
associata. popUpTo()
indica alla libreria di navigazione di rimuovere alcune destinazioni dallo stack posteriore durante la chiamata a navigate()
. Il valore del parametro è l'identificatore di una destinazione sullo stack posteriore. L'identificatore può essere un numero intero id
o una stringa route
.
Puoi includere un argomento per il parametro inclusive
con un valore di true
per indicare che anche la destinazione specificata in popUpTo()
deve uscire dallo stack di ritorno.
Per implementare questa funzionalità in modo programmatico, passa popUpTo()
a navigate()
come parte di
NavOptions
con inclusive
impostato su true
. Funziona sia in Compose che
Views.
Salva lo stato al popup
Quando utilizzi popUpTo
per navigare verso una destinazione, puoi scegliere di salvare gli stati di tutte le destinazioni estratti dallo stack di supporto.
Per attivare questa opzione, definisci popUpToSaveState
come true
nell'elemento
action
associato o chiama il numero NavController.navigate()
.
Quando raggiungi una destinazione, puoi anche definire restoreSaveState
come
true
per ripristinare automaticamente lo stato associato alla destinazione nella
proprietà destination
.
Esempio XML
Ecco un esempio di popUpTo
in XML, utilizzando un'azione:
<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"/>
Esempi di scrittura
Di seguito è riportato un esempio completo dello stesso in Scrivi:
@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")
}
}
In modo più dettagliato, puoi modificare il modo in cui chiami NavController.navigate()
nei seguenti modi:
// 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
}
Per informazioni generali su come passare opzioni a NavController.navigate()
, consulta la guida Navigare con le opzioni.
Pop con azioni
Durante la navigazione utilizzando un'azione, puoi facoltativamente rimuovere altre destinazioni dallo stack di riserva. Ad esempio, se la tua app prevede un flusso di accesso iniziale, dopo che un utente ha eseguito l'accesso dovresti estrarre tutte le destinazioni correlate all'accesso dallo stack di backup in modo che il pulsante Indietro non reindirizzi gli utenti al flusso di accesso.
Letture aggiuntive
Per ulteriori informazioni, consulta le seguenti pagine:
- Navigazione circolare: scopri come evitare uno stack eccessivo nei casi in cui i flussi di navigazione siano circolari.
- Destinazioni delle finestre di dialogo: leggi come le destinazioni delle finestre di dialogo introducono considerazioni esclusive sulla gestione del tuo back stack.