I currently have two NavGraphs in my app, one for authentication routes, like login and registration and one for the home routes when logged in.
I currently need to pass the navController as a parameter in every composable when I want to use it. That is definitely not scalable and so I'm wondering if it's possible to make it injectable so that I can just request it through a DI framework like Koin. I'm currently using Koin in my App so it would be good if I can just use it's dependency injection tools, to inject a navController as a singleton.
Current Navigation setup
I currently create the navController inside the MainActifity:
class MainActivity : AppCompatActivity() {
private lateinit var navController: NavHostController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
startKoin {
androidLogger(if (BuildConfig.DEBUG) Level.ERROR else Level.NONE)
androidContext(this@MainActivity)
modules(listOf(networkModule, viewModelModule, interactorsModule))
}
setContent {
navController = rememberAnimatedNavController()
SetupNavGraph(navController = navController)
}
}
}
I then pass it into the NavHost that holds the two NavGraphs:
fun SetupNavGraph(
navController: NavHostController
) {
AnimatedNavHost(
navController = navController,
startDestination = AUTH_GRAPH_ROUTE,
route = ROOT_GRAPH_ROUTE
) {
homeNavGraph(navController = navController)
authNavGraph(navController = navController)
}
}
Below is my NavGraph for all authentication routes. I also pass the NavController as a parameter so that I can use it inside the screen.
fun NavGraphBuilder.authNavGraph(
navController: NavController
) {
navigation(
startDestination = Screen.Login.route,
route = AUTH_GRAPH_ROUTE
) {
composable(
Screen.Login.route,
) {
val loginViewModel: LoginViewModel = getViewModel()
LoginScreen(
navController = navController,
state = loginViewModel.state.value,
onTriggerEvent = loginViewModel::onTriggerEvent
)
}
composable(
Screen.Register.route,
) {
val registerViewModel: RegisterViewModel = getViewModel()
RegisterScreen(
navController = navController,
state = registerViewModel.state.value,
onTriggerEvent = registerViewModel::onTriggerEvent
)
}
}
}
The NavGraph for all pages when logged in is similar to my auth one, so not worth showing.
It would be cool if I can just create a navController as a single through Koin but that is not possible because rememberNavController function can only be called inside a Composable.
Is there any solution in solving this problem of passing the navController into every nested composable?