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.
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 quel KotlinMutableList(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ûreté du typage 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 que la pile "Retour" puisse ê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ûreté du typage) :
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 calcul d'itinéraire (NavController par NavBackStack)
Remplacez votre NavController par un NavBackStack initialisé à l'aide de
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() } } )