Android Academy · Les

Navigatie tussen modules

Verbind features zonder koppeling.

Les 4 van 413 stappen

Navigatie tussen modules is een gratis Android Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Android Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Android Academy bevat in totaal 4 lessen.

De navigatie-uitdaging

Zodra features in afzonderlijke modules staan, ontstaat een nieuwe vraag: hoe opent :feature:home een scherm in :feature:profile zonder ervan afhankelijk te zijn? Als features elkaar rechtstreeks importeren, krijg je koppeling en loop je het risico op cycli.

In deze les leer je hoe je features via navigatie verbindt en ze tegelijkertijd onafhankelijk houdt.

Waar de NavHost staat

De enige NavHost staat in de module :app, de enige plek die alle features mag kennen. Elke feature levert zijn bestemmingen aan en :app voegt deze samen tot één graaf.

// app/AppNavHost.kt
@Composable
fun AppNavHost(navController: NavHostController = rememberNavController()) {
    NavHost(navController, startDestination = HomeRoute) {
        homeScreen(onProfileClick = { navController.navigate(ProfileRoute) })
        profileScreen(onBack = { navController.popBackStack() })
    }
}

Typeveilige routes

Moderne Navigation Compose ondersteunt typeveilige routes: een route is een @Serializable-object of een dataklasse, geen magische tekenreeks. Elke feature definieert zijn eigen routetype in zijn module en beheert zo zijn navigatiecontract.

// feature/profile/ProfileRoute.kt
import kotlinx.serialization.Serializable

@Serializable
data class ProfileRoute(val userId: String)

Features stellen NavGraphBuilder-extensies beschikbaar

De belangrijkste truc: elke feature stelt een uitbreidingsfunctie van NavGraphBuilder beschikbaar die zijn bestemming registreert. De feature beheert zijn scherm; :app roept alleen deze functie aan. De feature verwijst nooit naar andere features.

// feature/profile/ProfileNavigation.kt
fun NavGraphBuilder.profileScreen(onBack: () -> Unit) {
    composable<ProfileRoute> { backStackEntry ->
        val route: ProfileRoute = backStackEntry.toRoute()
        ProfileScreen(userId = route.userId, onBack = onBack)
    }
}

Ontkoppelen met navigatie-callbacks

Een feature mag nooit rechtstreeks navigate(SomeOtherFeatureRoute) aanroepen, omdat deze dan afhankelijk zou worden van de andere feature. In plaats daarvan stelt de feature lambda-callbacks beschikbaar, zoals onProfileClick. De module :app bepaalt waar deze daadwerkelijk naartoe gaan.

// feature/home/HomeNavigation.kt
fun NavGraphBuilder.homeScreen(onProfileClick: (String) -> Unit) {
    composable<HomeRoute> {
        HomeScreen(onUserClick = { userId -> onProfileClick(userId) })
    }
}
// :home does NOT know ProfileRoute exists.

De module :app verbindt alles

Alleen de module :app kent elke route en koppelt de callbacks aan echte navigatie. Dit is de enige plek waar koppeling acceptabel is — de hele taak van deze module is samenvoegen.

// app/AppNavHost.kt
NavHost(navController, startDestination = HomeRoute) {
    homeScreen(
        onProfileClick = { userId ->
            navController.navigate(ProfileRoute(userId)) // app knows both
        }
    )
    profileScreen(onBack = { navController.popBackStack() })
}

Argumenten veilig doorgeven

Omdat routes @Serializable-dataklassen zijn, worden argumenten tijdens het compileren op type gecontroleerd. Je leest ze binnen de bestemming terug met toRoute(). Geen parsing van tekenreeksen meer en geen crashes tijdens runtime door arguments?.getString(...).

// Reading arguments inside the destination
composable<ProfileRoute> { entry ->
    val args: ProfileRoute = entry.toRoute()
    ProfileScreen(userId = args.userId)
}

// Or directly in a ViewModel via SavedStateHandle
val route: ProfileRoute = savedStateHandle.toRoute()

Routetypen delen via een api-module

Soms moet een feature echt naar een andere navigeren en heeft deze het routetype nodig. Maak in plaats van afhankelijk te worden van de hele feature alleen de route beschikbaar in een kleine :feature:profile:api-module die alleen de @Serializable-route bevat. De zware :impl-module blijft privé.

// feature/profile/api  -> only the route type
@Serializable
data class ProfileRoute(val userId: String)

// feature/home/build.gradle.kts
// home may depend on the lightweight api to build the route,
// but never on :feature:profile:impl
implementation(project(":feature:profile:api"))

Geneste navigatie per feature

Een feature met meerdere schermen kan een volledige geneste graaf beschikbaar stellen met navigation<T>. De feature beheert zijn interne flow; :app koppelt de graaf alleen aan één toegangspunt.

// feature/onboarding/OnboardingNavigation.kt
fun NavGraphBuilder.onboardingGraph(onFinished: () -> Unit) {
    navigation<OnboardingGraph>(startDestination = WelcomeRoute) {
        composable<WelcomeRoute> { WelcomeScreen() }
        composable<PermissionsRoute> { PermissionsScreen(onDone = onFinished) }
    }
}

Deep links tussen modules

Typeveilige routes ondersteunen ook deep links. Een feature declareert een URI-patroon voor een deep link naar zijn bestemming; de NavHost van :app verwijst een binnenkomende link naar het juiste featurescherm, zonder import tussen features.

composable<ProfileRoute>(
    deepLinks = listOf(
        navDeepLink<ProfileRoute>(basePath = "https://myapp.com/profile")
    )
) { entry ->
    ProfileScreen(userId = entry.toRoute<ProfileRoute>().userId)
}

Het ontkoppelingspatroon samengevat

Samengevat zijn de regels eenvoudig:

  • Elke feature beheert zijn routetype en een NavGraphBuilder-extensie.
  • Features communiceren hun intentie via lambda-callbacks, niet via rechtstreekse navigatie.
  • Alleen :app kent alle features en koppelt callbacks aan echte routes.
  • Als een route gedeeld moet worden, stel je deze beschikbaar via een kleine :api-module.

Zo blijven features onafhankelijk, geschikt voor caching tijdens het bouwen en vrij van cycli.

Korte controle

In een app met meerdere modules moet :feature:home de gebruiker naar een scherm in :feature:profile sturen. Wat is de netste manier om de features ontkoppeld te houden?

Samenvatting: navigatie tussen modules

Je hebt geleerd hoe je features verbindt zonder ze aan elkaar te koppelen:

  • De enige NavHost staat in de dunne module :app.
  • Elke feature beheert een @Serializable-route en een NavGraphBuilder-extensie.
  • Features stellen callbacks beschikbaar in plaats van rechtstreeks naar andere features te navigeren.
  • Deel een route alleen via een kleine :api-module als dat echt nodig is; deep links en geneste grafen volgen hetzelfde patroon.

Daarmee is Multi-Module App Architecture voltooid: je kunt nu een schaalbare Android-codebase opsplitsen, verbinden en van navigatie voorzien.

Gratis beginnen

Leer Kotlin met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
36
Lessen
152

Veelgestelde vragen

Is de les “Navigatie tussen modules” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad Android Academy, waaronder “Navigatie tussen modules”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Android Academy bevat in totaal 4 lessen.

Wat leer ik in “Navigatie tussen modules”?

Verbind features zonder koppeling. Je oefent met Android Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Android Academy te beginnen?

Ervaring vooraf is niet nodig. Android Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Navigatie tussen modules”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Android Academy?

Ja. Elke les over Android Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Waarom modulariseren
  2. Feature- en coremodules
  3. Moduleafhankelijkheden beheren
  4. Navigatie tussen modules
← Terug naar Android Academy