L'API Navigation Compose vous permet de naviguer entre les composables d'une application Compose, tout en tirant parti du composant, de l'infrastructure et des fonctionnalités de Jetpack Navigation.
Cette page explique comment migrer d'une navigation Jetpack basée sur des fragments vers Navigation Compose, dans le cadre de la migration d'une UI basée sur les vues vers Jetpack Compose.
Conditions préalables à la migration
Vous pourrez migrer vers Navigation Compose une fois que vous pourrez remplacer tous vos fragments par les composables d'écran correspondants. Les composables d'écran peuvent contenir à la fois des contenus Compose et View, mais toutes les destinations de navigation doivent être des composables pour permettre la migration de Navigation Compose. En attendant, vous devez continuer à utiliser le composant Navigation basée sur des fragments dans votre codebase interop pour la vue et Compose. Pour en savoir plus, consultez la documentation sur l'interopérabilité de la navigation.
L'utilisation de Navigation Compose dans une application uniquement Compose n'est pas une condition préalable. Vous pouvez continuer à utiliser le composant Navigation basé sur des fragments, à condition de conserver des fragments pour héberger votre contenu composable.
Procédure de migration
Que vous suiviez notre stratégie de migration recommandée ou adoptiez une autre approche, toutes les destinations de navigation seront des composables d'écran, les fragments n'étant que des conteneurs composables. À ce stade, vous pouvez migrer vers Navigation Compose.
Si votre application suit déjà un modèle de conception défini par l'utilisateur et notre guide de l'architecture, la migration vers Jetpack Compose et Navigation Compose ne devrait pas nécessiter de refactorisation majeure pour les autres couches de votre application, en dehors de la couche d'UI.
Pour migrer vers Navigation Compose, procédez comme suit:
- Ajoutez la dépendance Navigation Compose à votre application.
Créez un composable
App-level
et ajoutez-le à votreActivity
en tant que point d'entrée Compose, en remplaçant la configuration de la mise en page de la vue:class SampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample) setContent { SampleApp(/* ... */) } } }
Configurez le
NavController
dans un emplacement où tous les composables qui doivent le référencer ont accès à celui-ci (il se trouve généralement dans votre composableApp
). Cette approche suit les principes du hissage d'état et vous permet d'utiliserNavController
comme source fiable pour naviguer entre les écrans composables et maintenir la pile "Retour" :@Composable fun SampleApp() { val navController = rememberNavController() // ... }
Créez le
NavHost
de votre application dans le composable App et transmettez lanavController
:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = "first") { // ... } }
Ajoutez les destinations
composable
pour créer votre graphique de navigation. Si chaque écran a déjà été migré vers Compose, cette étape consiste uniquement à extraire ces composables d'écran de vos fragments vers les destinationscomposable
:class FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { // FirstScreen(...) EXTRACT FROM HERE } } } } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = "first") { composable("first") { FirstScreen(/* ... */) // EXTRACT TO HERE } composable("second") { SecondScreen(/* ... */) } // ... } }
Si vous avez suivi les instructions sur la conception de l'interface utilisateur de Compose, en particulier sur la transmission des
ViewModel
et des événements de navigation aux composables, l'étape suivante consiste à modifier la façon dont vous fournissez leViewModel
à chaque composable d'écran. Vous pouvez souvent utiliser l'injection Hilt et son point d'intégration avec Compose et Navigation viahiltViewModel
:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
Remplacez tous les appels de navigation
findNavController()
par lesnavController
et transmettez-les en tant qu'événements de navigation à chaque écran composable, au lieu de transmettre l'intégralité denavController
. Cette approche suit les bonnes pratiques concernant l'exposition d'événements de fonctions composables aux appelants et conservenavController
comme source unique de référence.- Si vous avez déjà utilisé le plug-in Safe Args pour générer des itinéraires et des actions de navigation, remplacez-le par un route, c'est-à-dire un chemin d'accès de chaîne à votre composable unique pour chaque destination.
- Pour remplacer Safe Args lors de la transmission de données, consultez la section Naviguer avec des arguments.
Pour la sûreté du typage dans Navigation Compose, consultez la section Safe Args ci-dessous.
@Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = "first") { composable("first") { FirstScreen( onButtonClick = { // findNavController().navigate(firstScreenToSecondScreenAction) navController.navigate("second_screen_route") } ) } composable("second") { SecondScreen( onIconClick = { // findNavController().navigate(secondScreenToThirdScreenAction) navController.navigate("third_screen_route") } ) } // ... } }
Supprimez tous les fragments, les mises en page XML pertinentes, la navigation et les autres ressources inutiles, ainsi que les dépendances obsolètes de Fragment et de Jetpack Navigation.
Vous trouverez les mêmes étapes avec d'autres informations concernant Navigation Compose dans la documentation de configuration.
Cas d'utilisation courants
Quel que soit le composant Navigation que vous utilisez, les mêmes principes de navigation s'appliquent.
Voici quelques cas d'utilisation courants lors de la migration:
- Accéder à un composable
- Naviguer avec des arguments
- Liens profonds
- Navigation imbriquée
- Intégration avec la barre de navigation inférieure
- Intégration d'un composant de navigation personnalisé
Pour en savoir plus sur ces cas d'utilisation, consultez Naviguer avec Compose.
Safe Args
Contrairement à Jetpack Navigation, Navigation Compose ne permet pas d'utiliser le plug-in Safe Args pour générer du code. Au lieu de cela, vous pouvez assurer la sûreté du typage avec Navigation Compose en structurant votre code pour le rendre sûr au moment de l'exécution.
Récupérer des données complexes lors de la navigation
Navigation Compose est basé sur des routes de chaîne et, contrairement à Jetpack Navigation, n'est pas compatible avec la transmission de Parcelables et de Serializables personnalisés en tant qu'arguments.
Nous vous recommandons vivement de ne pas transmettre d'objets de données complexes lors de la navigation. Transmettez plutôt les informations minimales nécessaires, telles qu'un identifiant unique ou une autre forme d'ID, en tant qu'arguments lorsque vous effectuez des actions de navigation. Vous devez stocker des objets complexes sous forme de données dans une source unique de référence, telle que la couche de données. Pour en savoir plus, consultez la section Récupérer des données complexes lors de la navigation.
Si vos fragments transmettent des objets complexes en tant qu'arguments, envisagez d'abord de refactoriser votre code, de manière à pouvoir stocker et récupérer ces objets à partir de la couche de données. Consultez le dépôt Now in Android pour obtenir des exemples.
Limites
Cette section décrit les limites actuelles de Navigation Compose.
Migration incrémentielle vers Navigation Compose
Actuellement, vous ne pouvez pas utiliser Navigation Compose tout en utilisant des fragments comme destinations dans votre code. Pour commencer à utiliser Navigation Compose, toutes vos destinations doivent être des composables. Vous pouvez suivre cette demande de fonctionnalité sur l'Issue Tracker.
Animations de transition
À partir de Navigation 2.7.0-alpha01, la prise en charge de la définition de transitions personnalisées (auparavant à partir de AnimatedNavHost
) est directement prise en charge dans NavHost
. Lisez les notes de version pour plus d'informations.
En savoir plus
Pour en savoir plus sur la migration vers Navigation Compose, consultez les ressources suivantes:
- Atelier de programmation Navigation Compose: découvrez les principes de base de Navigation Compose grâce à un atelier de programmation pratique.
- Dépôt "Now in Android": application Android entièrement fonctionnelle, intégralement conçue avec Kotlin et Jetpack Compose, qui respecte les bonnes pratiques de conception et de développement Android, et qui inclut Navigation Compose.
- Migrer Sunflower vers Jetpack Compose: article de blog qui décrit le parcours de migration de l'application exemple Sunflower de Views vers Compose, qui inclut également la migration vers Navigation Compose.
- Jetnews pour chaque écran: article de blog qui décrit la refactorisation et la migration de l'exemple Jetnews pour prendre en charge tous les écrans avec Jetpack Compose et Navigation Compose.
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
- Naviguer avec Compose
- Compose et autres bibliothèques
- Autres points à prendre en compte