My goal is to to have a LoginScreen
from which I can navigate to an InternalScreen
. The InternalScreen
should have/be a bottom navigation bar that can navigate to multiple other screens/routes in the internal space.
This is what I imagined my NavGraph
was supposed to look like:
- LoginScreen
- internal space
- InternalScreen with BottomNavigation
- some fragment
- some other fragment
My idea was to create a Scaffold
with a BottomNavigationBar
in the InternalScreen
composable but I do not no where to put it in my NavGraph
since said NavGraph
also has to contain the different routes for the BottomNavigationBar
.
How should I approach this? I am sorry if this has already been answered, I couldn't find anything about this particular case.
I think the login screen/flow must be part of the application navigation flow. In summary, your application must react to a isLoggedIn
state, which should be global, and in case of the user is not logged in, the login screen must be displayed.
This is what I did:
@Composable
fun MainNavigation(
viewModel: MainViewModel,
navController: NavHostController,
) {
val auth = viewModel.auth
val initialRoute =
if (auth.isLoggedIn()) BooksFeature.route else LoginFeature.route
AnimatedNavHost(
navController,
startDestination = initialRoute
) {
loginGraph(auth, navController)
booksGraph(auth, navController)
settingsGraph(navController)
}
}
The MainNavigation
composable is the root of my app (which is called in setContent
at MainActivity
). Each feature of the app has a navigation graph. Like booksGraph
:
fun NavGraphBuilder.booksGraph(
auth: Auth, // this is a simple class which
// knows if the user is logged in
navController: NavHostController
) {
navigation(
route = BooksFeature.route,
startDestination = BooksList.route,
) {
composable("ScreenA") {
ScreenA()
}
...
}
}
In my activity (I'm using just one activity), I'm observing the login state and redirecting to the login screen properly.
private fun launchLoginObserver() {
lifecycleScope.launch(Dispatchers.Main) {
mainViewModel.isLoggedIn.collect { isLoggedInState ->
if (isLoggedInState == false) {
navigationController.navigate(LoginScreen.route) {
popUpTo(0) // reset stack
}
}
}
}
}
If you want to take a look into the full implementation, here is the link for my repository.