Les sections suivantes décrivent les stratégies permettant d'enregistrer votre pile "Retour" et de stocker l'état associé aux entrées de votre pile "Retour".
Enregistrer votre pile "Retour"
Il est essentiel de s'assurer que l'état de navigation de votre application persiste lors de divers événements de cycle de vie, y compris les modifications de configuration et la fin du processus, pour offrir une bonne expérience utilisateur. Dans Navigation 3, vous êtes propriétaire de votre pile "Retour". Il n'existe donc pas de consignes strictes sur la façon de la créer ou de l'enregistrer. Toutefois, Navigation 3 propose
une méthode pratique qui vous fournit une pile "Retour" enregistrable :
rememberNavBackStack.
Utiliser rememberNavBackStack
La fonction composable rememberNavBackStack est conçue pour créer une pile "Retour" qui persiste lors des modifications de configuration et de la fin du processus.
Pour que rememberNavBackStack fonctionne correctement, chaque clé de votre pile "Retour" doit respecter des exigences spécifiques :
- Implémenter l'interface
NavKey: chaque clé de la pile "Retour" doit implémenter l'interfaceNavKey. Il s'agit d'une interface de marqueur qui signale à la bibliothèque que la clé peut être enregistrée. - Avoir l'annotation
@Serializable: en plus d'implémenterNavKey, vos classes et objets clés doivent être marqués avec l'annotation@Serializable.
L'extrait suivant montre une implémentation correcte de rememberNavBackStack :
@Serializable data object Home : NavKey @Composable fun NavBackStack() { val backStack = rememberNavBackStack(Home) }
Mémoriser une pile "Retour" avec des sous-types de NavKey
La fonction composable rememberNavBackStack renvoie un NavBackStack<NavKey>.
Si votre application définit son propre sous-type de NavKey à partir duquel toutes ses clés héritent, vous pouvez conserver cette saisie en implémentant une fonction de mémorisation personnalisée, comme suit :
@Serializable sealed interface MyAppNavKey : NavKey @Serializable data object ScreenA: MyAppNavKey @Serializable data class ScreenB(val id: String): MyAppNavKey @Composable fun rememberMyAppNavBackStack(vararg elements: MyAppNavKey): NavBackStack<MyAppNavKey> { return rememberSerializable(serializer = serializer()) { NavBackStack(*elements) } } @Composable fun MyApp() { // defaultNavBackStack is NavBackStack<NavKey> val defaultNavBackStack = rememberNavBackStack(ScreenA) // myAppNavBackStack is NavBackStack<MyAppNavKey> val myAppNavBackStack = rememberMyAppNavBackStack(ScreenA) }
Pour obtenir d'autres exemples, y compris sur la gestion du polymorphisme ouvert, consultez
NavBackStackSamples.
Autre solution : stocker dans un ViewModel
Une autre approche pour gérer votre pile "Retour" consiste à la stocker dans un ViewModel.
Pour assurer la persistance lors de la fin du processus lorsque vous utilisez un ViewModel ou tout autre stockage personnalisé, vous devez procéder comme suit :
- Vous assurer que vos clés sont sérialisables : comme avec
rememberNavBackStack, vos clés de navigation doivent être sérialisables. - Gérer manuellement la sérialisation et la désérialisation : vous êtes responsable de
l'enregistrement manuel de la représentation sérialisée de chaque clé dans un stockage persistant et de sa
désérialisation (par exemple,
SharedPreferences, une base de données ou un fichier) lorsque votre application passe en arrière-plan ou est restaurée.
Définir l'étendue des ViewModel sur les NavEntry
ViewModels sont utilisés pour conserver l'état lié à l'UI lors des modifications de configuration,
telles que les rotations d'écran. Par défaut, ViewModels sont limités au
ViewModelStoreOwner le plus proche, qui est généralement votre Activity ou Fragment.
Toutefois, vous pouvez limiter un ViewModel à un NavEntry spécifique (c'est-à-dire un écran ou une destination spécifique) dans la pile "Retour", plutôt qu'à l'ensemble de l'Activity. Cela garantit que l'état du ViewModel n'est conservé que lorsque ce NavEntry particulier fait partie de la pile "Retour" et qu'il est effacé lorsque le NavEntry est supprimé.
La bibliothèque complémentaire androidx.lifecycle:lifecycle-viewmodel-navigation3 fournit
un NavEntryDecorator qui facilite cette opération. Ce décorateur fournit un ViewModelStoreOwner pour chaque NavEntry. Lorsque vous créez un ViewModel dans le contenu d'un NavEntry (par exemple, à l'aide de viewModel() dans Compose), il est automatiquement limité à la clé de ce NavEntry spécifique dans la pile "Retour". Cela signifie que le ViewModel est créé lorsque le NavEntry est ajouté à la pile "Retour" et effacé lorsqu'il est supprimé.
Pour utiliser NavEntryDecorator afin de limiter les ViewModel aux NavEntry, procédez comme suit :
- Ajoutez la dépendance
androidx.lifecycle:lifecycle-viewmodel-navigation3à votre fichierapp/build.gradle.kts. - Ajoutez le
rememberSaveableStateHolderNavEntryDecorator()à la liste desentryDecoratorslors de la construction d'unNavDisplay. - Ajoutez
rememberViewModelStoreNavEntryDecorator()à la liste desentryDecorators.
NavDisplay( entryDecorators = listOf( // Add the default decorators for managing scenes and saving state rememberSaveableStateHolderNavEntryDecorator(), // Then add the view model store decorator rememberViewModelStoreNavEntryDecorator() ), backStack = backStack, entryProvider = entryProvider { }, )