Migrer la navigation Jetpack vers Navigation Compose

L'API Navigation Compose vous permet de naviguer entre les composables dans une Compose, tout en tirant parti du composant Jetpack Navigation, de l'infrastructure et des fonctionnalités.

Cette page explique comment migrer d'une navigation Jetpack basée sur des fragments vers Navigation Compose, dans le cadre de la migration de l'UI basée sur les vues vers Jetpack Nouveau message.

Conditions préalables à la migration

Vous pourrez migrer vers Navigation Compose une fois que vous pourrez remplacer tous vos Fragments avec les composables d'écran correspondants Les composables d'écran peuvent contenir une combinaison de contenus Compose et View, mais toutes les destinations de navigation doivent composables pour permettre la migration de Navigation Compose. En attendant, vous devriez continuez à utiliser le composant Navigation basée sur des fragments dans votre vue d'interopérabilité et Codebase Compose. Pour en savoir plus, consultez la documentation sur l'interopérabilité de la navigation. des informations.

L'utilisation de Navigation Compose dans une application uniquement Compose n'est pas une condition préalable. Vous pouvez Continuez à utiliser le composant Navigation basé sur des fragments. Des fragments pour héberger votre contenu composable.

Procédure de migration

si vous suivez notre stratégie de migration recommandée ou que vous adoptez une autre approche, vous atteindrez un point où toutes les destinations de navigation des composables d'écran, les fragments n'agissant que comme des conteneurs composables. À cette adresse 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 sur , la migration vers Jetpack Compose et Navigation Compose ne devrait pas nécessitent des refactorisations majeures des autres couches de votre application, en dehors de la couche d'UI.

Pour migrer vers Navigation Compose, procédez comme suit:

  1. Ajoutez la dépendance Navigation Compose à votre application.
  2. Créez un composable App-level et ajoutez-le à votre Activity en tant que Point d'entrée de Compose, qui remplace la configuration de la mise en page Vue:

    class SampleActivity : ComponentActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample)
            setContent {
                SampleApp(/* ... */)
            }
        }
    }

  3. Configurez le NavController à un endroit où tous les composables qui ont besoin pour qu'il y ait accès (il se trouve généralement dans votre App du composable). Cette approche suit les principes du hissage d'état et vous permet d'utiliser NavController comme source de référence pour la navigation entre les écrans composables et maintien de la pile "Retour" :

    @Composable
    fun SampleApp() {
        val navController = rememberNavController()
        // ...
    }

  4. Créez le NavHost de votre application dans le composable App et transmettez la navController:

    @Composable
    fun SampleApp() {
        val navController = rememberNavController()
    
        SampleNavHost(navController = navController)
    }
    
    @Composable
    fun SampleNavHost(
        navController: NavHostController
    ) {
        NavHost(navController = navController, startDestination = "first") {
            // ...
        }
    }

  5. Ajoutez les destinations composable pour créer votre graphique de navigation. Si chaque l'écran a déjà été migré vers Compose, cette étape consiste uniquement extraire ces composables d'écran de vos fragments vers composable destinations:

    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(/* ... */)
            }
            // ...
        }
    }

  6. Si vous avez suivi les instructions sur la conception de l'architecture de votre interface utilisateur Compose, en particulier la manière dont les ViewModel et les événements de navigation doivent être transmis à l'étape suivante consiste à modifier la façon dont vous fournissez le ViewModel pour chaque composable d'écran. Vous pouvez souvent utiliser l'injection de Hilt et son intégration point avec Compose et Navigation via hiltViewModel:

    @Composable
    fun FirstScreen(
        // viewModel: FirstViewModel = viewModel(),
        viewModel: FirstViewModel = hiltViewModel(),
        onButtonClick: () -> Unit = {},
    ) {
        // ...
    }

  7. Remplacer tous les appels de navigation findNavController() par navController et les transmettre en tant qu'événements de navigation à chaque écran composable, plutôt que que de transmettre l'intégralité de navController. Cette approche suit la meilleure pratiques d'exposition des événements de fonctions composables aux appelants, conserve navController comme source unique de référence.

    1. 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 itinéraire, Chemin d'accès à votre composable sous forme de chaîne unique pour chaque destination.
    2. Pour remplacer Safe Args lors de la transmission de données, consultez la section Naviguer avec arguments.
    3. 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")
                      }
                  )
              }
              // ...
          }
      }

  8. Supprimez tous les fragments, les mises en page XML pertinentes, la navigation inutile et les autres ressources, et 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 le Documentation sur la configuration

Cas d'utilisation courants

Quel que soit le composant Navigation que vous utilisez, les mêmes principes s'appliquent.

Voici quelques cas d'utilisation courants lors de la migration:

Pour en savoir plus sur ces cas d'utilisation, consultez la section Naviguer avec Nouveau message.

Safe Args

Contrairement à Jetpack Navigation, Navigation Compose n'est pas compatible avec l'utilisation de l'API Safe Plug-in Args pour la génération de code. À la place, vous pouvez assurer la sûreté du typage Navigation Compose en structurant votre code pour le rendre sûr au niveau du typage de l'environnement d'exécution.

Récupérer des données complexes lors de la navigation

Navigation Compose est basé sur des routes sous forme de chaînes et, contrairement à Jetpack Navigation, ne permet pas de transmettre des Parcelables et 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 autre forme d'ID, en tant qu'arguments lors de l'exécution d'actions de navigation. Vous devez stocker des objets complexes sous forme de données dans une source unique de référence, telle que les calque. Pour en savoir plus, consultez la section Récupérer des données complexes lorsque navigation.

Si vos fragments transmettent des objets complexes en tant qu'arguments, envisagez de refactoriser votre code, de sorte que vous puissiez stocker et récupérer ces objets la couche de données. Consultez le dépôt Now in Android pour découvrir 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 en tant que des destinations dans votre code. Pour commencer à utiliser Navigation Compose, tous vos les destinations doivent être des composables. Vous pouvez suivre cette demande de fonctionnalité sur la Issue Tracker.

Animations de transition

À partir de Navigation 2.7.0-alpha01, possibilité de définir des paramètres personnalisés de AnimatedNavHost, est désormais directement disponible dans NavHost. Lisez les notes de version. pour en savoir plus.

En savoir plus

Pour en savoir plus sur la migration vers Navigation Compose, consultez les ressources suivantes : ressources:

  • Atelier de programmation Navigation Compose: découvrez les principes de base de Navigation Compose avec un atelier de programmation pratique.
  • Dépôt "Now in Android": une application Android entièrement fonctionnelle conçu entièrement avec Kotlin et Jetpack Compose, qui respecte la conception Android et de développement, et inclut Navigation Compose.
  • Migrer Sunflower vers Jetpack Compose: un article de blog documente le parcours de migration de l'application exemple Sunflower de Views vers Compose, qui inclut également la migration vers Navigation Compose.
  • Jetnews for every screen (Jetnews pour chaque écran) : cet article de blog présente la refactoriser et migrer l'exemple Jetnews pour prendre en charge tous les écrans avec Jetpack Compose et Navigation Compose