La navigation décrit la façon dont les utilisateurs se déplacent dans votre application. Ils interagissent avec les éléments de l'interface utilisateur, généralement en appuyant ou en cliquant dessus, et l'application répond en affichant un nouveau contenu. Si l'utilisateur souhaite revenir au contenu précédent, il utilise le geste Retour ou appuie sur le bouton Retour.
Modéliser l'état de navigation
Une façon pratique de modéliser ce comportement consiste à utiliser une pile de contenu. Lorsque l'utilisateur navigue vers l'avant pour accéder à de nouveaux contenus, ceux-ci sont placés au-dessus de la pile. Lorsqu'ils reviennent en arrière à partir de ce contenu, il est retiré de la pile et le contenu précédent s'affiche. En termes de navigation, cette pile est généralement appelée pile "Retour", car elle représente le contenu auquel l'utilisateur peut revenir.

Créer une pile de retour
Dans Navigation 3, la pile de retour ne contient pas de contenu. Il contient plutôt des références à du contenu, appelées clés. Les clés peuvent être de n'importe quel type, mais il s'agit généralement de classes de données sérialisables simples. L'utilisation de références plutôt que de contenu présente les avantages suivants :
- Il est facile de naviguer en appuyant sur les touches de la pile "Retour".
- Tant que les clés sont sérialisables, la pile "Retour" peut être enregistrée dans un stockage persistant, ce qui lui permet de survivre aux changements de configuration et à l'arrêt du processus. C'est important, car les utilisateurs s'attendent à pouvoir quitter votre application, y revenir plus tard et reprendre là où ils s'étaient arrêtés, avec le même contenu affiché. Pour en savoir plus, consultez Enregistrer votre pile de retour.
Un concept clé de l'API Navigation 3 est que vous êtes propriétaire de la pile arrière. La bibliothèque :
- S'attend à ce que votre pile de retour soit un
List<T>
soutenu par un état instantané, oùT
est le type de votre pile de retourkeys
. Vous pouvez utiliserAny
ou fournir vos propres clés plus fortement typées. Lorsque vous voyez les termes "push" ou "pop", l'implémentation sous-jacente consiste à ajouter ou supprimer des éléments à la fin d'une liste. - Observe votre pile "Retour" et reflète son état dans l'UI à l'aide d'un
NavDisplay
.
L'exemple suivant montre comment créer des clés et une pile de retour, et comment modifier la pile de retour en réponse aux événements de navigation de l'utilisateur :
// Define keys that will identify content data object ProductList data class ProductDetail(val id: String) @Composable fun MyApp() { // Create a back stack, specifying the key the app should start with val backStack = remember { mutableStateListOf<Any>(ProductList) } // Supply your back stack to a NavDisplay so it can reflect changes in the UI // ...more on this below... // Push a key onto the back stack (navigate forward), the navigation library will reflect the change in state backStack.add(ProductDetail(id = "ABC")) // Pop a key off the back stack (navigate back), the navigation library will reflect the change in state backStack.removeLastOrNull() }
Résoudre les clés de contenu
Le contenu est modélisé dans Navigation 3 à l'aide de NavEntry
, qui est une classe contenant une fonction composable. Il représente une destination, c'est-à-dire un élément de contenu unique vers lequel l'utilisateur peut avancer et revenir en arrière.
Un NavEntry
peut également contenir des métadonnées, c'-à-d. des informations sur le contenu. Ces métadonnées peuvent être lues par des objets conteneurs, comme NavDisplay
, pour les aider à décider comment afficher le contenu de NavEntry
. Par exemple, les métadonnées peuvent être utilisées pour remplacer les animations par défaut d'un NavEntry
spécifique. NavEntry
metadata
est un mappage de clés String
vers des valeurs Any
, ce qui permet un stockage polyvalent des données.
Pour convertir un key
en NavEntry
, créez un fournisseur d'entrées. Il s'agit d'une fonction qui accepte un key
et renvoie un NavEntry
pour ce key
. Il est généralement défini comme paramètre lambda lors de la création d'un NavDisplay
.
Il existe deux façons de créer un fournisseur d'entrées : en créant directement une fonction lambda ou en utilisant le DSL entryProvider
.
Créer directement une fonction de fournisseur d'entrées
En général, vous créez une fonction Entry Provider à l'aide d'une instruction when
, avec une branche pour chacune de vos clés.
entryProvider = { key -> when (key) { is ProductList -> NavEntry(key) { Text("Product List") } is ProductDetail -> NavEntry( key, metadata = mapOf("extraDataKey" to "extraDataValue") ) { Text("Product ${key.id} ") } else -> { NavEntry(Unit) { Text(text = "Invalid Key: $it") } } } }
Utiliser le DSL entryProvider
Le DSL entryProvider
peut simplifier votre fonction lambda en vous évitant de tester chacun de vos types de clés et de construire un NavEntry
pour chacun d'eux.
Pour ce faire, utilisez la fonction de création entryProvider
. Il inclut également un comportement de secours par défaut (générant une erreur) si la clé est introuvable.
entryProvider = entryProvider { entry<ProductList> { Text("Product List") } entry<ProductDetail>( metadata = mapOf("extraDataKey" to "extraDataValue") ) { key -> Text("Product ${key.id} ") } }
Notez les points suivants dans l'extrait :
entry
est utilisé pour définir unNavEntry
avec le type et le contenu composable donnés.entry
accepte un paramètremetadata
pour définirNavEntry.metadata
.
Afficher la pile "Retour"
La pile "Retour" représente l'état de navigation de votre application. Chaque fois que la pile "Retour" change, l'UI de l'application doit refléter le nouvel état de la pile "Retour". Dans Navigation 3, un NavDisplay
observe votre pile "Retour" et met à jour son UI en conséquence. Construisez-le avec les paramètres suivants :
- Votre pile de retour : elle doit être de type
SnapshotStateList<T>
, oùT
correspond au type de vos clés de pile de retour. Il s'agit d'unList
observable qui déclenche la recomposition deNavDisplay
lorsqu'il change. - Un
entryProvider
pour convertir les clés de votre pile de retour en objetsNavEntry
. - Vous pouvez également fournir un lambda au paramètre
onBack
. Celle-ci est appelée lorsque l'utilisateur déclenche un événement Retour.
L'exemple suivant montre comment créer un NavDisplay
.
data object Home data class Product(val id: String) @Composable fun NavExample() { val backStack = remember { mutableStateListOf<Any>(Home) } NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, entryProvider = { key -> when (key) { is Home -> NavEntry(key) { ContentGreen("Welcome to Nav3") { Button(onClick = { backStack.add(Product("123")) }) { Text("Click to navigate") } } } is Product -> NavEntry(key) { ContentBlue("Product ${key.id} ") } else -> NavEntry(Unit) { Text("Unknown route") } } } ) }
Par défaut, NavDisplay
affiche le NavEntry
le plus haut de la pile "Retour" dans une mise en page à un seul volet. L'enregistrement suivant montre l'exécution de cette application :

NavDisplay
avec deux destinations.Synthèse
Le schéma suivant montre comment les données circulent entre les différents objets de Navigation 3 :

Les événements de navigation déclenchent des modifications. Les clés sont ajoutées ou supprimées de la pile "Retour" en réponse aux interactions utilisateur.
La modification de l'état de la pile de retour déclenche la récupération du contenu.
NavDisplay
(un composable qui affiche une pile "Retour") observe la pile "Retour". Dans sa configuration par défaut, il affiche l'entrée de pile "Retour" la plus haute dans une mise en page à un seul volet. Lorsque la clé supérieure de la pile de retour change,NavDisplay
utilise cette clé pour demander le contenu correspondant au fournisseur d'entrées.Le fournisseur de la fiche fournit le contenu. Le fournisseur d'entrées est une fonction qui résout une clé en
NavEntry
. Lorsqu'il reçoit une clé duNavDisplay
, le fournisseur d'entrée fournit leNavEntry
associé, qui contient à la fois la clé et le contenu.Le contenu s'affiche.
NavDisplay
reçoitNavEntry
et affiche le contenu.