Niklas Bolwede
06/21/2021, 10:59 AMNiklas Bolwede
06/21/2021, 11:00 AM@Composable
fun MainApp(mView: MapView) {
val mainViewModel: MainViewModel = viewModel()
val navController = rememberNavController()
val scaffoldState = rememberScaffoldState()
val isLoggedIn = mainViewModel.isLoggedIn.value
val bottomBar: @Composable () -> Unit = {
BottomBar(
navController = navController,
screens = screensFromBottomNav
)
}
Scaffold(
bottomBar = {
if(isLoggedIn) { bottomBar() }
},
scaffoldState = scaffoldState,
) {
Box(modifier = Modifier
.padding(0.dp,it.calculateTopPadding(), 0.dp, it.calculateBottomPadding())
){
NavigationHost(
navController = navController,
mainViewModel = mainViewModel,
mView = mView
)
}
}
}
@Composable
fun NavigationHost(
navController: NavController,
mainViewModel: MainViewModel,
mView: MapView)
{
NavHost(
navController = navController as NavHostController,
startDestination = Screen.LoginScreen.Login.route,//Screen.Nav.Home.route,
) {
composable(Screen.Nav.Home.route) {
val homeViewModel: HomeViewModel = viewModel()
mainViewModel.currentScreen.value = Screen.Nav.Home
HomeScreen(mainViewModel = mainViewModel, homeViewModel = homeViewModel)
}
composable(Screen.Nav.Map.route) {
val mapViewModel: MapViewModel = viewModel()
mainViewModel.currentScreen.value = Screen.Nav.Map
MapScreen(mainViewModel = mainViewModel, mapViewModel = mapViewModel, mView = mView)
}
composable(Screen.Nav.Profile.route) {
val profileViewModel: ProfileViewModel = viewModel()
mainViewModel.currentScreen.value = Screen.Nav.Profile
ProfileScreen(mainViewModel = mainViewModel, profileViewModel = profileViewModel, navController = navController)
}
composable(Screen.LoginScreen.Login.route){
val loginViewModel: LoginViewModel = viewModel()
mainViewModel.currentScreen.value = Screen.LoginScreen.Login
LoginScreen(mainViewModel = mainViewModel, loginViewModel = loginViewModel, navController = navController)
}
}
}
Niklas Bolwede
06/21/2021, 11:00 AM@Composable
fun BottomBar(modifier: Modifier = Modifier, screens: List<Screen.Nav>, navController: NavController) {
BottomNavigation(modifier = modifier) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
screens.forEach { screen ->
BottomNavigationItem(
icon = { Icon(imageVector = screen.icon, contentDescription = "") },
label = { Text(screen.title) },
selected = currentRoute == screen.route,
onClick = {
navController.navigate(screen.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
}
sealed class Screen(val route: String, val title: String) {
sealed class Nav(
route: String,
title: String,
val icon: ImageVector
) : Screen(route, title) {
object Home : Nav("home", "Home", Icons.Filled.Home)
object Map : Nav("map", "Map", Icons.Filled.Place)
object Profile : Nav("profile", "Profile", Icons.Filled.Person)
}
sealed class LoginScreen(
route: String,
title: String
) : Screen(route, title) {
object Login : LoginScreen("login", "Login")
}
}
val screensFromBottomNav = listOf(
Screen.Nav.Home,
Screen.Nav.Map,
Screen.Nav.Profile
)
class MainViewModel : ViewModel() {
val currentScreen: MutableState<Screen> = mutableStateOf(Screen.LoginScreen.Login)
val isLoggedIn: MutableState<Boolean> = mutableStateOf(false)
fun login(navController: NavController){
isLoggedIn.value = true
navController.navigate(Screen.Nav.Home.route)
}
fun logout(navController: NavController){
isLoggedIn.value = false
navController.navigate(Screen.LoginScreen.Login.route)
}
override fun onCleared() {
super.onCleared()
}
}
class HomeViewModel: ViewModel() {
var clickCountHome: MutableState<Int> = mutableStateOf(0)
}
Ian Lake
06/21/2021, 7:40 PMIan Lake
06/21/2021, 7:45 PMnavigate()
without popUpTo
you're only adding a new destination to the back stack, which is why your logout
isn't doing what you think it is doing.Niklas Bolwede
06/22/2021, 9:27 AMfun login(navController: NavController){
isLoggedIn.value = true
navController.popBackStack()
}
fun logout(navController: NavController){
isLoggedIn.value = false
navController.popBackStack()
}
Scaffold(
bottomBar = {
if(isLoggedIn) { bottomBar() }
},
scaffoldState = scaffoldState,
) {
Box(modifier = Modifier
.padding(0.dp,it.calculateTopPadding(), 0.dp, it.calculateBottomPadding())
){
if (isLoggedIn){
NavigationHost(
navController = navController,
mainViewModel = mainViewModel,
mView = mView
)
}else {
LoginScreen(mainViewModel = mainViewModel, navController = navController)
}
}
}
It now seems to work.