Navigation Compose — is een Jetpack-bibliotheek voor declaratieve navigatie in Android-applicaties gebouwd op Jetpack Compose. In plaats van FragmentManager of Intent-gebaseerde navigatie biedt Navigation Compose een uniforme routegraaf die wordt beheerd via NavController en NavHost. Volgens Google I/O (2025)-gegevens is Navigation Compose de aanbevolen navigatiemethode voor Compose-applicaties, die in meer dan 70% van de nieuwe projecten wordt gebruikt. De bibliotheek ondersteunt het doorgeven van getypeerde argumenten, diepe links, overgangsanimaties en integratie met ViewModel via SavedStateHandle.
Belangrijkste punten
Navigation Compose — is een bibliotheek uit de Jetpack-suite die een navigatieframework biedt voor Compose-applicaties. De bibliotheek is gebaseerd op dezelfde principes als Navigation Component voor het View-systeem, maar aangepast aan de declaratieve aard van Compose: in plaats van FragmentTransaction worden composable-functies gebruikt en de navigatiegraaf wordt gebouwd via Kotlin DSL.
Het belangrijkste verschil tussen Navigation Compose en klassieke navigatie — de afwezigheid van FragmentManager. Elk scherm is een composable-functie die in NavHost wordt gerenderd bij overeenkomst van de route. Back stack slaat geen Fragment op, maar een record met route, argumenten en status. Dit vereenvoudigt de architectuur en elimineert levenscyclusconflicten die kenmerkend zijn voor Fragment-navigatie.
Volgens Google (2025) heeft Navigation Compose de weg van experimental naar stable afgelegd en maakt het deel uit van Jetpack sinds versie 2.8.0. De bibliotheek ondersteunt Material3, Type-Safe Navigation (via Kotlin Serialization), geneste grafen en modularisatie. De enige beperking — de bibliotheek ondersteunt geen multi-back stack voor BottomNavigation zonder handmatige configuratie, hoewel Google hieraan werkt.
De architectuur van Navigation Compose is gebouwd rond drie entiteiten: NavController (stackbeheer), NavHost (grafcontainer) en NavDestination (afzonderlijke route met composable). De interactie ertussen is declaratief: de ontwikkelaar beschrijft routes en argumenten, de bibliotheek verwerkt laad-, bewaar- en herstelstatussen.
NavController — het centrale element van Navigation Compose dat de navigatiestack beheert. Het wordt aangemaakt via rememberNavController() en doorgegeven aan NavHost. NavController slaat de back stack, het huidige ingangspunt op en ondersteunt uitgestelde acties (deeplink na initialisatie van de graaf).
@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") ?: ""
)
}
}
}
Belangrijkste methoden van NavController: navigate(route) — navigeren naar een route, popBackStack() — terugkeren naar het vorige scherm, navigateAndClear(route) — navigeren met het leegmaken van de stack. NavOptions bepalen het gedrag: launchSingleTop voorkomt duplicatie, popUpTo maakt de stack leeg tot de opgegeven route, restoreState herstelt de vorige status.
Voor toegang tot NavController vanuit diep geneste composable-functies gebruikt u NavHostController via CompositionLocal. LocalNavController wordt beschikbaar gesteld in ScopedNavController binnen NavHost. Buiten NavHost (bijv. in BottomNavigation) wordt de controller doorgegeven via parameters of ViewModel.
NavHost — is een composable-container die NavController verbindt met de routegraaf. Elke route wordt gedeclareerd via composable(route, arguments, deepLinks), waarbij route een routestring is met optionele placeholders {param}. Bij overeenkomst van de huidige route met route rendert NavHost het bijbehorende composable-blok.
De routegraaf wordt hiërarchisch opgebouwd: grafen kunnen worden genest via navigation() voor het groeperen van routes binnen een module. Geneste grafen hebben een eigen startDestination en worden verenigd onder een gemeenschappelijk route-voorvoegsel. Dit maakt het mogelijk een modulaire architectuur te organiseren, waarbij elke feature-module zijn subgraaf registreert.
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 verwerkt automatisch de systeem Terug-knop (back press) via LocalBackDispatcher. In Material3 Scaffold wordt standaard NavController overgenomen voor correcte werking van BottomNavigation. NavHost hercreëert composable bij routewijziging, maar behoudt de status via rememberSaveable voor invoervelden en scrollen.
Navigation Compose ondersteunt het doorgeven van getypeerde argumenten tussen schermen via routeparameters en NavType. Parameters worden gedefinieerd in route als {paramName} met opgave van het type via arguments in composable(). NavType ondersteunt String, Int, Long, Float, Boolean, Parcelable en Serializable.
| Argumenttype | NavType | Voorbeeld route |
|---|---|---|
| String | NavType.StringType | "profile/{name}" |
| Int | NavType.IntType | "item/{id}" |
| Boolean | NavType.BoolType | "settings?enabled={flag}" |
| Parcelable | NavType.ParcelableType | "details/{item}" |
| Float | NavType.FloatType | "map?lat={lat}&lng={lng}" |
Argumenten worden geëxtraheerd uit NavBackStackEntry via arguments?.getType(key). Voor verplichte parameters gebruikt u defaultValue, voor optionele — nullable. Parcelable-ondersteuning werkt alleen met Kotlin Parcelize of de bibliotheek kotlinx.parcelize. Voor complexe objecten wordt aanbevolen de ID door te geven en gegevens te laden via ViewModel, niet het hele object te serialiseren.
Sinds Navigation 2.8.0 is Type-Safe Navigation met Kotlin Serialization beschikbaar: routes worden gedefinieerd als dataklassen, argumenten als velden. Dit vervangt string-routes door getypeerde objecten en elimineert fouten in routenamen. Voor migratie is de Kotlin Serialization-plugin en de afhankelijkheid navigation-compose-typesafe vereist.
@Serializable
/* sealed class Route */
sealed class ProfileRoute(val route: String) {
data object Home : ProfileRoute("home")
data class Profile(val userId: String) : ProfileRoute("profile/{userId}")
}
Deep Links — navigatiemechanisme waarmee een specifiek scherm van de applicatie kan worden geopend via een URL of intent-filter. In Navigation Compose worden diepe links geconfigureerd via de parameter deepLinks in composable() en automatisch verwerkt bij overeenkomst van URI met het patroon.
Een Deep Link wordt gedefinieerd als een lijst UriPattern: "https://example.com/profile/{userId}". Parameters uit URI worden automatisch toegewezen aan routeargumenten. NavController verwerkt de deep link bij het starten van de applicatie (via intent) en tijdens het gebruik (via impliciete deep links). Voor het verwerken van wachtende deep links wordt handleDeepLink() in NavController gebruikt na initialisatie van de graaf.
Volgens Google wordt het configureren van deep links aanbevolen voor: pushmeldingen (Firebase Dynamic Links), e-mailverificatie, het delen van inhoud en navigatie vanuit web-links. Voor Android 12+ wordt Digital Asset Links gebruikt voor verificatie van de autoriteit van de deep link. AndroidManifest.xml moet een intent-filter met autoVerify="true" bevatten voor het openen van links zonder dialoog.
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") ?: "")
}
Beperkingen van deep links in Navigation Compose: de bibliotheek ondersteunt geen uitgestelde deep links — een deep link wordt pas verwerkt nadat NavHost de graaf volledig heeft opgebouwd. Als een deep link arriveert vóór initialisatie van de graaf, moet deze worden uitgesteld via intent?.data en worden verwerkt in LaunchedEffect. Voor Firebase Dynamic Links gebruikt u Firebase Dynamic Links SDK in combinatie met Navigation Compose.
Navigation Compose ondersteunt overgangsanimatie via de parameters enterTransition, exitTransition, popEnterTransition en popExitTransition in composable(). Animaties worden geïmplementeerd via Compose Animation API: fadeIn, slideInHorizontally, expandIn en andere. Standaard is animatie uitgeschakeld — schermen worden onmiddellijk vervangen.
Typische animatiescenario's: slideInHorizontally voor voorwaartse navigatie (scherm komt van rechts binnen), slideOutHorizontally voor terugkeer (scherm gaat naar rechts). Voor BottomNavigation wordt vaker fade-animatie zonder verschuiving gebruikt. Animaties worden ingesteld via NavHost en toegepast op alle composables, tenzij individuele animaties zijn gespecificeerd.
NavHost(
navController = navController,
startDestination = "home",
enterTransition = { slideInHorizontally() + fadeIn() },
exitTransition = { slideOutHorizontally() + fadeOut() },
popEnterTransition = { fadeIn() },
popExitTransition = { slideOutHorizontally() + fadeOut() }
) { /* composable */ }
Animaties kunnen voor elke composable afzonderlijk worden overschreven door animatieparameters rechtstreeks in composable() door te geven. Belangrijk: animaties mogen niet conflicteren met de systeemanimatie van back press. Voor shared element transition is de bibliotheek accompanist-navigation-animation of een aangepaste implementatie via Modifier.graphicsLayer vereist. Volgens Android Developers (2025) gebruikt 80% van de productie-applicaties horizontale slide-animatie voor standaardnavigatie.
Veelgestelde vragen
Navigation Compose werkt zonder Fragment, gebruikt composable-functies en Kotlin DSL voor de graaf. Navigation Component (View) is gebaseerd op FragmentManager en XML-grafen. De Compose-versie is eenvoudiger, sneller en heeft geen Fragment-levenscycli. Navigation Component voor View is alleen geschikt voor hybride applicaties.
Het wordt aanbevolen de ID van het object door te geven en gegevens te laden via ViewModel met SavedStateHandle. Als het object eenvoudig is — gebruik dan Parcelable via kotlinx.parcelize. Het rechtstreeks doorgeven van grote objecten via argumenten (Bundle) is beperkt tot ~1 MB en kan TransactionTooLargeException veroorzaken.
Ja, via de functie navigation(route, startDestination) binnen NavHost. Geneste grafen hebben een eigen startDestination en worden verenigd onder een gemeenschappelijk route-voorvoegsel. Dit maakt het mogelijk een modulaire architectuur te organiseren met geïsoleerde grafen voor elke feature-module.
NavController verwerkt automatisch back press via BackHandler uit Compose. Roep navController.popBackStack() aan bij indrukken van Terug. Voor aangepaste verwerking (bevestiging van afsluiten) gebruikt u BackHandler(enabled = condition) { callback } vóór het aanroepen van popBackStack().
Momenteel wordt Navigation Compose niet ondersteund in Compose Multiplatform. Voor het iOS-gedeelte van cross-platform projecten gebruikt u Voyager of Decompose. Google werkt aan KMP-ondersteuning, maar er zijn geen releasedata. Voor Android-only projecten is Navigation Compose de enige aanbevolen optie.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook