Les sections suivantes décrivent des stratégies permettant d'enregistrer votre pile "Retour" et de stocker l'état associé aux entrées de votre pile "Retour".
Enregistrer la pile "Retour"
S'assurer que l'état de navigation de votre application persiste dans les différents événements de cycle de vie, y compris les modifications de configuration et l'arrêt du processus, est essentiel pour une bonne expérience utilisateur. Dans Navigation 3, vous êtes le 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" pouvant être enregistrée : rememberNavBackStack
.
Utiliser rememberNavBackStack
La fonction composable rememberNavBackStack
est conçue pour créer une pile "Retour" qui persiste en cas de modification de la configuration et de fin du processus.
Pour que rememberNavBackStack
fonctionne correctement, chaque touche de votre pile "Retour" doit respecter des exigences spécifiques:
- Implémenter l'interface
NavKey
: chaque touche de la pile "Retour" doit implémenter l'interfaceNavKey
. Il s'agit d'une interface de repère qui signale à la bibliothèque que la clé peut être enregistrée. - Disposer de l'annotation
@Serializable
: en plus d'implémenterNavKey
, vos classes et objets clés doivent être marqués avec l'annotation@Serializable
.
L'extrait de code suivant montre une implémentation correcte de rememberNavBackStack
:
@Serializable data object Home : NavKey @Composable fun NavBackStack() { val backStack = rememberNavBackStack(Home) }
Autre solution: stocker dans un ViewModel
Vous pouvez également gérer votre pile "Retour" en la stockant dans un ViewModel
.
Pour la persistance en cas d'arrêt du processus lorsque vous utilisez un ViewModel
ou tout autre stockage personnalisé, vous devez:
- Assurez-vous que vos clés sont sérialisables: comme pour
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 à partir de celui-ci (par exemple,
SharedPreferences
, une base de données ou un fichier) lorsque votre application passe en arrière-plan ou est restaurée.
Délimiter les ViewModel
aux NavEntry
ViewModels
permet de conserver l'état lié à l'UI lors des modifications de configuration, telles que les rotations d'écran. Par défaut, les ViewModels
sont limitées 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) sur la pile "Retour", plutôt que l'ensemble de la Activity
. Cela garantit que l'état de ViewModel
n'est conservé que lorsque ce NavEntry
particulier fait partie de la pile "Retour" et est effacé lorsque NavEntry
est supprimé.
La bibliothèque de modules complémentaires androidx.lifecycle:lifecycle-viewmodel-navigation3
fournit un NavEntryDecorator
qui facilite cela. 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), son champ d'application est automatiquement limité à la clé de cet NavEntry
spécifique sur la pile "Retour". Cela signifie que ViewModel
est créé lorsque NavEntry
est ajouté à la pile "Retour" et effacé lorsqu'il est supprimé.
Pour utiliser NavEntryDecorator
pour définir le champ d'application des ViewModel
sur les NavEntry
, procédez comme suit:
- Ajoutez la dépendance
androidx.lifecycle:lifecycle-viewmodel-navigation3
à votre fichierapp/build.gradle.kts
. - Ajoutez
rememberSavedStateNavEntryDecorator()
à la liste desentryDecorators
lors de la création d'unNavDisplay
. - Ajoutez d'autres décorateurs dans votre
NavDisplay
.
NavDisplay( entryDecorators = listOf( // Add the default decorators for managing scenes and saving state rememberSceneSetupNavEntryDecorator(), rememberSavedStateNavEntryDecorator(), // Then add the view model store decorator rememberViewModelStoreNavEntryDecorator() ), backStack = backStack, entryProvider = entryProvider { }, )