Navigation 3 représente un changement fondamental dans la façon dont Jetpack Compose gère l'état de navigation et offre des avantages architecturaux significatifs par rapport à Navigation 2.
Découvrez les modifications architecturales et les étapes nécessaires pour migrer une application Wear Compose de Navigation 2 vers Navigation 3.
. Il se concentre sur les étapes de migration spécifiques aux applications Wear OS, telles que la transition versSwipeDismissableSceneStrategy.
Principaux avantages de Navigation 3
- Contrôle direct de la pile "Retour" : Le
NavBackStackn'est fondamentalement qu' une liste mutable d'objetsNavKey, représentant l'historique des écrans que l'utilisateur a consultés. Vous la contrôlez exactement comme vous le feriez pour n'importe quelMutableList(add,removeLast,clear). Vous manipulez directement la liste pour effectuer des actions de navigation, comme ajouter une clé pour avancer ou en supprimer une pour revenir en arrière. - Conception axée sur Compose : la pile "Retour" est modélisée comme un état observable standard La modification de votre historique de navigation se comporte exactement comme la mise à jour de n'importe quel autre état Compose, ce qui déclenche automatiquement la recomposition pour afficher l'écran actuel.
- Sécurité des types par défaut : les itinéraires basés sur des chaînes sont entièrement éliminés. La navigation utilise des objets de données et des classes de données sérialisables.
- Présentations découplées (stratégies de scène) : la couche de transition de l'UI
(
NavDisplayetSwipeDismissableSceneStrategy) est entièrement séparée du suivi de l'état (NavBackStack), ce qui permet une intégration plus simple des transitions de navigation Wear OS intégrées.
Procédure de migration
1. Mettre à jour les dépendances
Supprimez l'ancienne dépendance androidx.wear.compose:compose-navigation et introduisez les nouvelles dépendances divisées de Navigation 3, ainsi que la prise en charge de la sérialisation Kotlin.
Suppression :
implementation("androidx.wear.compose:compose-navigation:...")
Ajout :
implementation("androidx.navigation3:navigation3-runtime:...") // State logic
implementation("androidx.navigation3:navigation3-ui:...") // Display logic
implementation("androidx.wear.compose:compose-navigation3:...") // Wear gestures
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:...") // Requires compiler plugin
2. Mettre à jour les destinations pour implémenter NavKey
Dans Navigation 2, vous avez peut-être utilisé des chaînes ou des objets génériques pour le routage. Dans
Navigation 3, vous devez implémenter l'interface de marqueur NavKey et
annoter chaque objet d'écran avec @Serializable.
Pourquoi est-ce nécessaire ? Pour garantir que la pile "Retour" peut être enregistrée et
restaurée en cas d'arrêt du processus, le navigation3-runtime sous-jacent s'appuie sur
kotlinx-serialization pour sérialiser l'état.
Avant (Navigation 2 – Itinéraires génériques avec sécurité des types) :
sealed class Nav2Screen { data object Landing : Nav2Screen() data object List : Nav2Screen() }
Après (Navigation 3 – NavKey + sérialisable) :
@Serializable sealed interface MigrationScreen : NavKey { @Serializable data object Landing : MigrationScreen @Serializable data object List : MigrationScreen }
3. Remplacer la logique de routage (NavController par NavBackStack)
Remplacez votre NavController par un NavBackStack initialisé via
rememberNavBackStack. Vous devez également instancier le
SwipeDismissableSceneStrategy spécifiquement pour Wear OS.
Avant (Navigation 2) :
val navController = rememberSwipeDismissableNavController()
Après (Navigation 3) :
val backStack = rememberNavBackStack(MigrationScreen.Landing as NavKey) val strategy = rememberSwipeDismissableSceneStrategy<NavKey>()
4. Remplacer NavHost par NavDisplay et le DSL entryProvider
Le conteneur NavHost et son compilateur composable("route") { ... } interne
DSL sont remplacés par NavDisplay et le entryProvider {
entry<Key> { ... } } DSL.
Avant (Navigation 2) :
SwipeDismissableNavHost(navController = navController, startDestination = "menu") { composable("menu") { GreetingScreen( onShowList = { navController.navigate("list") } ) } composable("list") { ListScreen() } }
Après (Navigation 3) :
NavDisplay( backStack = backStack, sceneStrategies = listOf(strategy), entryProvider = entryProvider { entry<MigrationScreen.Landing> { GreetingScreen( onShowList = { backStack.add(MigrationScreen.List) } ) } entry<MigrationScreen.List> { ListScreen() } } )