NavController
contient une "pile "Retour"". contenant les destinations auxquelles
a visité ce lieu. 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". La
NavController
place donc les éléments vers le haut et les fait sortir du haut
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 que
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 le
pile "Retour" et les états de toutes les destinations sont sortis de la pile "Retour". Vous pouvez
Ensuite, restaurez la pile "Retour" et les destinations lorsque vous accédez à cette destination.
ultérieurement. Cela vous permet de conserver l'état d'une destination donnée et d'avoir
plusieurs piles "Retour".
Pour effectuer cette opération par programmation, spécifiez saveState = true
lorsque vous ajoutez popUpTo
à
vos options de navigation.
Vous pouvez également spécifier restoreState = true
dans vos options de navigation pour
restaure automatiquement la pile "Retour" et l'état associé à
vers votre destination.
Exemple :
navController.navigate(
route = route,
navOptions = navOptions {
popUpTo<A>{ saveState = true }
restoreState = true
}
)
Pour activer l'enregistrement et la restauration de l'état au format XML, définissez popUpToSaveState
sur true
et restoreState
respectivement comme true
dans le action
associé.
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"/>
Exemple Compose
Voici ce même exemple dans 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")
}
}
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".