NavHost — wat is het, graaf bouwen en routes in Jetpack Compose

Auteur: IT Sectr Gepubliceerd: 2026-06-30 Leestijd: 7 min

NavHost is een composable-container die fungeert als toegangspunt voor de navigatiegraaf in Jetpack Compose. Het verbindt NavController met een set routes en rendert het huidige scherm op basis van de back stack-status. Volgens Android Developers (2025) is NavHost een verplichte component voor elke Compose-app met navigatie. Binnen NavHost worden composable-routes geregistreerd met optionele argumenten, deep links en animatie. Elke route is een gewone composable-functie die NavBackStackEntry met overgangsgegevens ontvangt. NavHost verwerkt automatisch back press, statusopslag en herstel bij reconfiguratie.

Belangrijkste punten

  • NavHost — composable-container die NavController met de routegraaf verbindt en het huidige scherm rendert
  • composable() — functie voor het registreren van een route met route, argumenten, deep links en overgangsanimatie
  • startDestination — de beginroute die wordt geopend bij het maken van NavHost
  • Argumenten worden gedefinieerd via navArgument met NavType voor getypeerde gegevensoverdracht tussen schermen
  • Animatie wordt globaal of individueel geconfigureerd via enterTransition, exitTransition parameters

Wat is NavHost in Jetpack Compose?

NavHost is een composable-functie die een container biedt voor het weergeven van het huidige navigatiescherm. NavHost accepteert NavController, startDestination en de routegraaf die via Kotlin DSL is opgebouwd. Bij het wijzigen van de huidige route schakelt NavHost de weergegeven composable met de opgegeven animatie.

NavHost werkt als een schermschakelaar: het volgt de huidige NavBackStackEntry van NavController en rendert het bijbehorende composable-blok. Elk scherm is een onafhankelijke composable-functie die NavBackStackEntry met routeargumenten ontvangt. Alle schermen bestaan in dezelfde compositieboom, maar NavHost toont er slechts één tegelijk, waarbij de andere via animatie worden verborgen.

In tegenstelling tot FragmentManager maakt NavHost geen Fragment voor elk scherm. De hele levenscyclus wordt beheerd via CompositionLifecycle — composable-functies hebben geen onStart/onResume, dus voor bijwerkingen worden LaunchedEffect en DisposableEffect gebruikt. NavHost abonneert zich automatisch op NavController en herstelt de UI bij routewijziging.

Volgens Google is NavHost een stabiele API sinds Navigation 2.4.0. Vanaf 2.8.0 ondersteunt NavHost Type-Safe Navigation via Kotlin Serialization, wat string-routes vervangt door data-klassen. NavHost ondersteunt ook geneste grafen, wat navigatie per module mogelijk maakt.

NavHost wordt gemaakt met twee verplichte parameters: navController (NavHostController-instantie) en startDestination (string van de eerste schermroute). De derde parameter is het builder-blok waarin alle routes worden geregistreerd via composable(), navigation() en dialog().

kotlin
@Composable
fun AppNavHost(navController: NavHostController) {
    NavHost(
        navController = navController,
        startDestination = "home"
    ) {
        composable("home") { HomeScreen(navController) }
        composable("settings") { SettingsScreen(navController) }
    }
}

startDestination is de route die wordt geopend bij de eerste start van NavHost. Als de back stack leeg is, voegt NavHost automatisch startDestination toe aan de stapel. Bij reconfiguratie (schermrotatie) herstelt NavHost de laatste route uit savedState, niet startDestination.

Voor BottomNavigation is startDestination een van de routes van het onderste paneel. De overige routes van het paneel worden als afzonderlijke composable-items toegevoegd. NavHost moet worden geplaatst in Scaffold.content — waar de hoofdinhoud van de app wordt weergegeven. NavHost beslaat de volledige beschikbare hoogte minus TopAppBar en BottomNavigation.

Routes registreren via composable

De functie composable(route, arguments, deepLinks, enterTransition, exitTransition, content) registreert een route in de NavHost-graaf. De parameter route is een string die het pad beschrijft met optionele placeholders in de vorm {paramName}. De placeholder wordt bij navigatie vervangen door een concrete waarde.

Het content-blok ontvangt NavBackStackEntry waaruit argumenten worden gehaald. De composable-functie van het scherm wordt alleen weergegeven wanneer de huidige NavController-route overeenkomt met route. Bij niet-overeenkomst wordt de composable uit de compositie verwijderd, maar de status kan worden opgeslagen via rememberSaveable of ViewModel met SavedStateHandle.

kotlin
composable(
    route = "article/{articleId}",
    arguments = listOf(navArgument("articleId") {
        type = NavType.IntType
        defaultValue = 0
    }),
    deepLinks = listOf(navDeepLink { uriPattern = "https://app.example/article/{articleId}" })
) { backStackEntry ->
    val articleId = backStackEntry.arguments?.getInt("articleId") ?: 0
    ArticleScreen(articleId = articleId)
}

Het aantal composable-items in NavHost kan variëren van een paar tot honderden. Voor grote apps worden routes opgedeeld in modules en verbonden via geneste grafen. Elke composable kan eigen animatie-, deep link- en argumentinstellingen hebben.

Argumenten en getypeerde routeparameters

Routeargumenten worden gedefinieerd via de parameter arguments: List<NamedNavArgument> in composable(). Elk argument wordt opgegeven via navArgument(name) { type; defaultValue }. NavType bepaalt het argumenttype: StringType, IntType, LongType, FloatType, BoolType, ParcelableType en ReferenceType.

RouteparameterVoorbeeld routeNavType
Pad (path)„user/{id}"NavType.IntType
Query„search?q={query}"NavType.StringType
Optioneel„details/{id}?tab={tab}"StringType + defaultValue=""
Parcelable„checkout/{order}"NavType.ParcelableType

Argumenten worden uit NavBackStackEntry gehaald via arguments?.getInt("id"). Voor verplichte argumenten kan defaultValue ontbreken — NavType gebruikt dan null. Voor optionele argumenten is defaultValue verplicht, anders gooit navigatie een uitzondering bij afwezigheid van de parameter.

Sinds Navigation 2.8.0 wordt Type-Safe Navigation aanbevolen: definieer een sealed class of data class voor routes met Kotlin Serialization. Gebruik in plaats van string-route composable<RouteType> { backStackEntry -> }. Dit elimineert typefouten in route en genereert automatisch NavType voor argumenten. Voor migratie voegt u de afhankelijkheid navigation-compose-typesafe en de Kotlin Serialization-plugin toe.

Geneste navigatiegrafen

nested graphs — mechanisme voor het groeperen van routes in NavHost via de functie navigation(route, startDestination). Een geneste graaf heeft een eigen route-prefix en startDestination, en al zijn routes zijn toegankelijk via de prefix. nested graphs worden gebruikt voor modulaire architectuur, waarbij elke feature-module zijn eigen subgraaf registreert.

Voordelen van geneste grafen: isolatie van routes binnen de module, uniforme back stack voor een groep schermen, navigatie op prefix zonder interne structuur bloot te geven. Bijvoorbeeld, de graaf „auth" bevat „auth/login" en „auth/register". Navigatie is mogelijk via het volledige routepad of via prefix met omleiding naar startDestination.

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) }
    }
}

nested graphs ondersteunen het doorgeven van argumenten op graafniveau: parameters gedeclareerd in het routepad van de graaf worden doorgegeven aan alle interne routes. Gebruik popBackStack(route) om een geneste graaf te wissen — het verwijdert alle interne items. Geneste grafen hebben geen dieptebeperking, maar voor leesbaarheid wordt maximaal 3 niveaus aanbevolen.

Animaties en overgangen aanpassen

NavHost ondersteunt overgangsanimatie tussen composable-routes via de parameters enterTransition, exitTransition, popEnterTransition en popExitTransition. Animaties worden één keer voor NavHost gedefinieerd en toegepast op alle routes, of individueel voor elke composable. Standaard is animatie uitgeschakeld.

Typische configuratie: enterTransition = slideInHorizontally(initialOffsetX = { it }) — het scherm komt van rechts binnen; exitTransition = slideOutHorizontally(targetOffsetX = { -it }) — het scherm verdwijnt naar links. Voor pop-animatie zijn de richtingen gespiegeld: het scherm komt van links binnen en verdwijnt naar rechts. Voor BottomNavigation wordt fadeIn/fadeOut zonder slide gebruikt.

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

Custom animaties worden gemaakt via de Compose Animation API: AnimatedContentTransitionScope biedt toegang tot containerafmetingen, animatievoortgang en direction. Voor shared element transition (een element dat soepel naar een ander scherm overgaat) is de Accompanist Navigation Animation-bibliotheek of een custom implementatie via sharedElement Modifier vereist. Volgens Android Developers (2025) wordt de standaard slide-animatie (binnenkomst van rechts, vertrek naar links) gebruikt in 80% van de Android-apps met navigatie.

Veelgestelde vragen

Kunnen meerdere NavHosts in één Activity worden gebruikt?

Technisch gezien wel, maar het wordt afgeraden. Elke NavHost creëert een onafhankelijke back stack, wat de eenheid van navigatie verbreekt. Uitzondering zijn gescheiden gebieden, zoals een NavHost voor hoofdinhoud en een NavHost voor BottomSheet met eigen navigatie.

Wat is het verschil tussen NavHost en Scaffold in Compose?

NavHost — navigatiecontainer die schermen schakelt. Scaffold — lay-out van de hele pagina (TopAppBar, BottomNavigation, FloatingActionButton). Meestal wordt NavHost in Scaffold.content geplaatst. Scaffold beheert geen navigatie, maar biedt alleen slots voor UI-componenten.

Hoe geef ik ViewModel door tussen schermen via NavHost?

ViewModel wordt gemaakt binnen NavBackStackEntry via viewModel(). Voor het delen van ViewModel tussen schermen gebruikt u parentNavController: koppel de gedeelde ViewModel aan de bovenliggende entry. Alternatief — DI (Hilt/Koin) met scope op NavGraph.

Waarom maakt NavHost de composable opnieuw bij elke overgang?

Dit is normaal gedrag — NavHost verwijdert de composable uit de compositie bij het verlaten van een route. Gebruik rememberSaveable voor UI-status en ViewModel met SavedStateHandle voor bedrijfslogica om de status te behouden.

Hoe voeg ik 404-afhandeling (onbekende route) toe in NavHost?

Voeg de laatste route composable("404") toe en navigeer ernaar bij een onbekende deep link. NavHost heeft geen catch-all route — controleer de route in de Deep Link intent-handler vóór navigate(). Als route niet wordt gevonden — navigeer naar 404.

Samenvatting

  • NavHost — composable-container van Navigation Compose, die NavController met de routegraaf verbindt en het huidige scherm rendert
  • composable() registreert een route met route, argumenten (NavType), deep links en animatie
  • startDestination — de beginroute die wordt geopend bij de eerste start van NavHost
  • Argumenten worden doorgegeven via {param}-placeholders met NavType voor typering en defaultValue voor optionele parameters
  • Geneste grafen via navigation() maken het mogelijk routes per module te groeperen met geïsoleerde back stack
  • Animatie van overgangen wordt geconfigureerd via enterTransition/exitTransition met Compose Animation API
  • NavHost verwerkt automatisch back press, statusopslag en deep links zonder extra code

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.

Bespreek het project

Lees ook