NavController
contient une pile "Retour" contenant les destinations que l'utilisateur a consultées. Lorsque l'utilisateur accède aux écrans de votre application, NavController
ajoute et supprime des destinations vers et depuis la pile "Retour".
En tant que pile, la pile "Retour" est une structure de données de type "dernier arrivé, premier sorti".
NavController
déplace donc les éléments vers le haut et les fait sortir du haut de la pile.
Comportement de base
Voici les principaux points à prendre en compte concernant le comportement de la pile "Retour" :
- Première destination : lorsque l'utilisateur ouvre l'application,
NavController
place la première destination en haut de la pile "Retour". - Transfert vers la pile : chaque appel de
NavController.navigate()
place la destination donnée en haut de la pile. - Affichage de la première destination : appuyer sur Haut ou Retour appelle respectivement les méthodes
NavController.navigateUp()
etNavController.popBackStack()
. Elles font sortir la première destination de la pile. Consultez la page Principes de navigation pour en savoir plus sur la différence entre Haut et Retour.
Retour en arrière
La méthode NavController.popBackStack()
tente de faire sortir la destination actuelle de la pile "Retour" et d'accéder à la destination précédente. Cela fait reculer l'utilisateur d'une étape dans son historique de navigation. Elle renvoie une valeur booléenne indiquant si elle a bien fait revenir l'utilisateur à la destination.
Revenir à une destination spécifique
Vous pouvez également utiliser popBackStack()
pour accéder à une destination spécifique. Pour ce faire, utilisez l'une de ses surcharges. Plusieurs surcharges vous permettent de transmettre un identifiant, tel qu'un id
entier ou une chaîne route
. Ces surcharges redirigent l'utilisateur vers la destination associée à l'identifiant donné. Il est important que tous les éléments de la pile soient placés au-dessus de cette destination.
Ces surcharges prennent également une valeur booléenne inclusive
, qui détermine si NavController
doit également afficher la destination spécifiée de la pile "Retour" après y avoir accédé.
Prenons l'exemple suivant :
navController.popBackStack(R.id.destinationId, true)
Ici, NavController
revient à la destination avec l'ID entier destinationId
. Comme la valeur de l'argument inclusive
est true
, NavController
affiche également la destination donnée de la pile "Retour".
Gérer un retour ayant échoué
Lorsque popBackStack()
renvoie false
, un appel ultérieur à NavController.getCurrentDestination()
renvoie null
. Cela signifie que l'application a fait sortir la dernière destination de la pile "Retour". Dans ce cas, l'utilisateur ne voit qu'un écran vide.
Cela peut se produire dans les cas suivants :
popBackStack()
n'a rien supprimé de la pile.popBackStack()
a fait sortir une destination de la pile "Retour" et celle-ci est désormais vide.
Pour résoudre ce problème, vous devez ensuite accéder à une nouvelle destination ou appeler finish()
sur votre activité pour l'arrêter, comme le montre l'extrait de code suivant :
kotlin
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish()
}
java
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish();
}
Accéder à une destination
Pour supprimer des destinations de la pile "Retour" lorsque vous passez d'une destination à une autre, ajoutez un argument popUpTo()
à l'appel de fonction navigate()
associé. popUpTo()
indique à la bibliothèque Navigation de supprimer certaines destinations de la pile "Retour" dans le cadre de l'appel de navigate()
. La valeur du paramètre correspond à l'identifiant d'une destination dans la pile "Retour". L'identifiant peut être un id
entier ou une chaîne route
.
Vous pouvez inclure un argument pour le paramètre inclusive
avec la valeur true
pour indiquer que la destination que vous avez spécifiée dans popUpTo()
doit également sortir de la pile "Retour".
Pour implémenter ceci par programmation, transmettez popUpTo()
à navigate()
dans NavOptions
avec inclusive
défini sur true
. Cela fonctionne à la fois dans Compose et dans Vues.
Enregistrer l'état lors de l'accès à une destination
Lorsque vous utilisez popUpTo
pour accéder à une destination, vous pouvez éventuellement enregistrer les états de toutes les destinations sorties de la pile "Retour".
Pour activer cette option, définissez popUpToSaveState
sur true
dans l'action
associée ou appelez NavController.navigate()
.
Lorsque vous accédez à une destination, vous pouvez également définir restoreSaveState
sur true
pour restaurer automatiquement l'état associé à la destination dans la propriété destination
.
Exemple de code XML
Voici un exemple de popUpTo
à l'aide d'une action en XML :
<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"/>
Exemples Compose
Voici ce même exemple dans 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")
}
}
Plus précisément, vous pouvez modifier la façon dont vous appelez NavController.navigate()
de différentes manières :
// 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
}
Pour obtenir des informations générales sur la transmission d'options à NavController.navigate()
, consultez le guide Naviguer avec des options.
Accéder à une destination à l'aide d'actions
Lorsque vous utilisez une action, vous pouvez éventuellement supprimer des destinations supplémentaires de la pile "Retour". Par exemple, si votre application implique un processus d'authentification initial, une fois qu'un utilisateur s'est connecté, vous devez supprimer toutes les destinations liées à l'authentification de la pile "Retour" afin que le bouton "Retour" ne redirige pas les utilisateurs vers ce processus.
Autres ressources
Pour en savoir plus, consultez les pages suivantes :
- Navigation circulaire : découvrez comment éviter une surcharge de la pile "Retour" dans les cas où les flux de navigation sont circulaires.
- Destinations des boîtes de dialogue : découvrez comment les destinations des boîtes de dialogue introduisent des considérations uniques sur votre façon de gérer votre pile "Retour".