Search code examples
androidandroid-jetpack-composeandroid-productflavorsjetpack-compose-navigationwhite-labelling

The best way to define flavor-specific navigation for NavHost with Jetpack Compose


I have a multi-flavored, modularized app. Currently, I have 4 flavors and just one feature module, e.g. :feature:cars

At the moment, the :feature:cars module should be connected only to 3 flavors out of 4. But in the future, there will be more flavors and feature modules.

For now, I define additional composable inside the NavHost using the addSpecificNavigation function that is created in each flavor folder, where the :feature:cars module is not used, the function does nothing, and in the other 3 files the code is exactly the same.

I don't like this solution, but I can't figure out how to do it in a more correct way. Any advices?

Current NavHost:

NavHost(navController, startDestination = startDestinationRoute) {
        addSpecificNavigation(navController)

        composable(Onboarding.route) {
            OnboardingScreen(appState = appState)
        }
        ...

}

FlavorA/FlavorSpecificNavigation:

fun NavGraphBuilder.addSpecificNavigation(navController: NavHostController) {
    //no differences yet
}

FlavorB/FlavorSpecificNavigation:

fun NavGraphBuilder.addSpecificNavigation(navController: NavHostController) {
    composable(Destination.Cars.route) {
        CarsScreen()
    }

    composable(Destination.CreateCar.route) {
        CreateCarScreen()
    }
    ...
}

Solution

  • So I decide to do it by moving all module-specific navigation to the extension function in this module.

    in the :feature:cards, navigation/CardsNavigation.kt:

    fun NavGraphBuilder.cardsScreens() {
        composable(Destination.Cars.route) {
            CarsScreen()
        }
    
        composable(Destination.CreateCar.route) {
            CreateCarScreen()
        }
    }
    

    and in the FlavorB/FlavorSpecificNavigation:

    fun NavGraphBuilder.addSpecificNavigation(navController: NavHostController) {
        cardsScreens()
    }