Navigation Compose : qu'est-ce que c'est, architecture et travail en développement

Auteur : IT Sectr Publié le : 2026-06-29 Temps de lecture : 8 min

Navigation Compose est une bibliothèque Jetpack pour la navigation déclarative au sein d'applications Android construites avec Jetpack Compose. Au lieu de FragmentManager ou de la navigation basée sur Intent, Navigation Compose propose un graphe de routes unique géré via NavController et NavHost. Selon Google I/O (2025), Navigation Compose est la méthode de navigation recommandée pour les applications Compose, utilisée dans plus de 70% des nouveaux projets. La bibliothèque prend en charge le passage d'arguments typés, les liens profonds, les animations de transition et l'intégration avec ViewModel via SavedStateHandle.

Points clés

  • Navigation Compose — une bibliothèque Jetpack pour la navigation déclarative dans Compose avec un graphe de routes unifié
  • NavController — le contrôleur central qui gère la pile de navigation et l'état de la pile arrière
  • NavHost — un conteneur qui définit le graphe de routes via des fonctions composable avec route
  • Arguments sont passés via NavType et SavedStateHandle avec prise en charge de paramètres typés
  • Liens profonds — navigation via des URL externes avec analyse automatique des arguments depuis l'URI

Qu'est-ce que Navigation Compose ?

Navigation Compose est une bibliothèque de la suite Jetpack fournissant un framework de navigation pour les applications Compose. La bibliothèque est basée sur les mêmes principes que le composant de navigation pour le système View, mais adaptée à la nature déclarative de Compose : au lieu de FragmentTransaction, des fonctions composable sont utilisées, et le graphe de navigation est construit via Kotlin DSL.

La différence clé entre Navigation Compose et la navigation classique est l'absence de FragmentManager. Chaque écran est une fonction composable qui est rendue dans NavHost lorsque la route correspond. La pile arrière stocke non pas un Fragment, mais un enregistrement avec la route, les arguments et l'état. Cela simplifie l'architecture et élimine les conflits de cycle de vie typiques de la navigation basée sur Fragment.

Selon Google (2025), Navigation Compose est passé d'expérimental à stable et fait partie de Jetpack depuis la version 2.8.0. La bibliothèque prend en charge Material3, la navigation type-safe (via Kotlin Serialization), les graphes imbriqués et la modularisation. La seule limitation est que la bibliothèque ne prend pas en charge la pile arrière multiple pour BottomNavigation sans configuration manuelle, bien que Google travaille dessus.

L'architecture de Navigation Compose s'articule autour de trois entités : NavController (gestion de la pile), NavHost (conteneur du graphe) et NavDestination (route individuelle avec composable). L'interaction entre elles est déclarative : le développeur décrit les routes et les arguments, et la bibliothèque gère les états de chargement, de conservation et de restauration.

NavController est l'élément central de Navigation Compose, gérant la pile de navigation. Il est créé via rememberNavController() et passé à NavHost. NavController stocke la pile arrière, le point d'entrée actuel et prend en charge les actions différées (deeplink après l'initialisation du graphe).

kotlin
@Composable
fun AppNavigation() {
    val navController = rememberNavController()
    NavHost(navController = navController, startDestination = "home") {
        composable("home") { HomeScreen(navController) }
        composable("profile/{userId}") { backStackEntry ->
            ProfileScreen(
                userId = backStackEntry.arguments?.getString("userId") ?: ""
            )
        }
    }
}

Méthodes principales de NavController : navigate(route) — naviguer vers une route, popBackStack() — revenir à l'écran précédent, navigateAndClear(route) — naviguer et vider la pile. NavOptions spécifie le comportement : launchSingleTop empêche les doublons, popUpTo vide la pile jusqu'à la route spécifiée, restoreState restaure l'état précédent.

Pour accéder à NavController depuis des fonctions composable profondément imbriquées, utilisez NavHostController via CompositionLocal. LocalNavController est fourni dans ScopedNavController à l'intérieur de NavHost. En dehors de NavHost (par exemple, dans BottomNavigation), le contrôleur est passé via des paramètres ou ViewModel.

NavHost est un conteneur composable qui relie NavController au graphe de routes. Chaque route est déclarée via composable(route, arguments, deepLinks), où route est une chaîne de route avec des espaces réservés {param} optionnels. Lorsque la route actuelle correspond, NavHost rend le bloc composable correspondant.

Le graphe de routes est construit hiérarchiquement : les graphes peuvent être imbriqués via navigation() pour regrouper les routes au sein d'un module. Les graphes imbriqués ont leur propre startDestination et sont combinés sous un préfixe de route commun. Cela permet d'organiser une architecture modulaire où chaque module de fonctionnalité enregistre son propre sous-graphe.

kotlin
NavHost(
    navController = navController,
    startDestination = "main"
) {
    composable("main") { MainScreen(navController) }
    navigation(
        route = "auth",
        startDestination = "auth/login"
    ) {
        composable("auth/login") { LoginScreen(navController) }
        composable("auth/register") { RegisterScreen(navController) }
    }
}

NavHost gère automatiquement le bouton Retour système (back press) via LocalBackDispatcher. Dans Material3 Scaffold, il capture par défaut NavController pour le bon fonctionnement de BottomNavigation. NavHost recrée le composable lorsque la route change, mais préserve l'état via rememberSaveable pour les champs de saisie et le défilement.

Passage d'arguments entre écrans

Navigation Compose prend en charge le passage d'arguments typés entre écrans via des paramètres de route et NavType. Les paramètres sont spécifiés dans la route comme {paramName} avec le type indiqué via arguments dans composable(). NavType prend en charge String, Int, Long, Float, Boolean, Parcelable et Serializable.

Type d'argumentNavTypeExemple de route
StringNavType.StringType"profile/{name}"
IntNavType.IntType"item/{id}"
BooleanNavType.BoolType"settings?enabled={flag}"
ParcelableNavType.ParcelableType"details/{item}"
FloatNavType.FloatType"map?lat={lat}&lng={lng}"

Les arguments sont extraits de NavBackStackEntry via arguments?.getType(key). Pour les paramètres obligatoires, utilisez defaultValue, pour les optionnels — nullable. La prise en charge de Parcelable fonctionne uniquement avec Kotlin Parcelize ou la bibliothèque kotlinx.parcelize. Pour les objets complexes, il est recommandé de passer un ID et de charger les données via ViewModel, plutôt que de sérialiser l'objet entier.

Depuis Navigation 2.8.0, la navigation type-safe avec Kotlin Serialization a été introduite : les routes sont définies comme des classes de données et les arguments comme des champs. Cela remplace les routes chaîne par des objets typés et élimine les erreurs dans les noms de routes. La migration nécessite le plugin Kotlin Serialization et la dépendance navigation-compose-typesafe.

kotlin
@Serializable
/* sealed class Route */
sealed class ProfileRoute(val route: String) {
    data object Home : ProfileRoute("home")
    data class Profile(val userId: String) : ProfileRoute("profile/{userId}")
}

Les liens profonds sont un mécanisme de navigation permettant d'ouvrir un écran spécifique de l'application via une URL ou un intent-filter. Dans Navigation Compose, les liens profonds sont configurés via le paramètre deepLinks dans composable() et sont traités automatiquement lorsque l'URI correspond au modèle.

Un lien profond est spécifié comme une liste UriPattern : "https://example.com/profile/{userId}". Les paramètres URI sont automatiquement mappés aux arguments de la route. NavController traite les liens profonds au démarrage de l'application (via intent) et pendant le fonctionnement (via des liens profonds implicites). Pour gérer les liens profonds en attente, utilisez handleDeepLink() dans NavController après l'initialisation du graphe.

Selon Google, les liens profonds sont recommandés pour : les notifications push (Firebase Dynamic Links), la vérification des e-mails, le partage de contenu et la navigation croisée à partir de liens web. Pour Android 12+, les Digital Asset Links sont utilisés pour vérifier l'autorité du lien profond. AndroidManifest.xml doit contenir un intent-filter avec autoVerify="true" pour ouvrir les liens sans dialogue.

kotlin
composable(
    route = "profile/{userId}",
    arguments = listOf(navArgument("userId") { type = NavType.StringType }),
    deepLinks = listOf(
        navDeepLink { uriPattern = "https://example.com/profile/{userId}" }
    )
) { backStackEntry ->
    ProfileScreen(userId = backStackEntry.arguments?.getString("userId") ?: "")
}

Limitations des liens profonds dans Navigation Compose : la bibliothèque ne prend pas en charge les liens profonds différés — un lien profond est traité seulement après que NavHost a complètement construit le graphe. Si un lien profond arrive avant l'initialisation du graphe, il doit être différé via intent?.data et traité dans LaunchedEffect. Pour Firebase Dynamic Links, utilisez le SDK Firebase Dynamic Links avec Navigation Compose.

Animations de transition entre écrans

Navigation Compose prend en charge les animations de transition via les paramètres enterTransition, exitTransition, popEnterTransition et popExitTransition dans composable(). Les animations sont implémentées à l'aide de l'API d'animation Compose : fadeIn, slideInHorizontally, expandIn et autres. Par défaut, l'animation est désactivée — les écrans sont remplacés instantanément.

Scénarios d'animation typiques : slideInHorizontally pour la navigation avant (l'écran entre par la droite), slideOutHorizontally pour le retour (l'écran sort par la droite). Pour BottomNavigation, l'animation de fondu sans glissement est plus couramment utilisée. Les animations sont définies via NavHost et s'appliquent à tous les composables sauf si des animations individuelles sont spécifiées.

kotlin
NavHost(
    navController = navController,
    startDestination = "home",
    enterTransition = { slideInHorizontally() + fadeIn() },
    exitTransition = { slideOutHorizontally() + fadeOut() },
    popEnterTransition = { fadeIn() },
    popExitTransition = { slideOutHorizontally() + fadeOut() }
) { /* composable */ }

Les animations peuvent être remplacées pour chaque composable individuellement en passant des paramètres d'animation directement dans composable(). Il est important que les animations n'entrent pas en conflit avec l'animation de retour système. Pour la transition d'élément partagé, la bibliothèque accompanist-navigation-animation ou une implémentation personnalisée via Modifier.graphicsLayer est nécessaire. Selon Android Developers (2025), 80% des applications de production utilisent une animation de glissement horizontal pour la navigation standard.

Questions fréquentes

En quoi Navigation Compose diffère du composant de navigation pour View ?

Navigation Compose fonctionne sans Fragment, en utilisant des fonctions composable et Kotlin DSL pour le graphe. Le composant de navigation (View) est basé sur FragmentManager et des graphes XML. La version Compose est plus simple, plus rapide et n'a pas de cycles de vie Fragment. Le composant de navigation pour View ne convient qu'aux applications hybrides.

Comment passer un objet complexe entre écrans ?

Il est recommandé de passer l'ID de l'objet et de charger les données via ViewModel avec SavedStateHandle. Si l'objet est simple, utilisez Parcelable via kotlinx.parcelize. Passer de gros objets directement via les arguments (Bundle) est limité à ~1 Mo et peut provoquer TransactionTooLargeException.

Navigation Compose prend-il en charge les graphes imbriqués ?

Oui, via la fonction navigation(route, startDestination) dans NavHost. Les graphes imbriqués ont leur propre startDestination et sont combinés sous un préfixe de route commun. Cela permet d'organiser une architecture modulaire avec des graphes isolés pour chaque module de fonctionnalité.

Comment gérer le bouton Retour système dans Navigation Compose ?

NavController gère automatiquement l'appui sur Retour via BackHandler de Compose. Appelez navController.popBackStack() lorsque Retour est pressé. Pour un traitement personnalisé (confirmation de sortie), utilisez BackHandler(enabled = condition) { callback } avant d'appeler popBackStack().

Peut-on utiliser Navigation Compose avec Jetpack Compose Multiplatform ?

Actuellement, Navigation Compose n'est pas pris en charge dans Compose Multiplatform. Pour la partie iOS des projets multiplateformes, utilisez Voyager ou Decompose. Google travaille sur le support KMP, mais il n'y a pas de calendrier de publication. Pour les projets Android uniquement, Navigation Compose est la seule option recommandée.

Résumé

  • Navigation Compose — une bibliothèque Jetpack pour la navigation déclarative dans Compose, fonctionnant via un graphe de routes et NavController
  • NavController gère la pile arrière et fournit les méthodes navigate, popBackStack pour la navigation
  • NavHost relie le contrôleur au graphe via composable(), prenant en charge les graphes imbriqués pour une architecture modulaire
  • Arguments sont passés via NavType avec prise en charge de String, Int, Parcelable et de la navigation type-safe avec Kotlin Serialization
  • Liens profonds sont configurés via navDeepLink avec UriPattern pour la navigation externe depuis des URL et notifications push
  • Animation des transitions est définie via enterTransition, exitTransition en utilisant l'API d'animation Compose
  • La bibliothèque ne prend pas en charge KMP et la pile arrière multiple pour BottomNavigation sans configuration supplémentaire

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi