What I use:
Kotlin, Jetpack Compose
What I want to do:
After clicking "Log In" text I would want to navigate user to the log in form
What I currently have:
MainActivity.kt
class MainActivity : ComponentActivity() {
private val viewModel: MainActivityViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
installSplashScreen().apply {
setKeepOnScreenCondition {
viewModel.isLoading.value
}
}
setContent {
RestaurantioTheme {
Surface(Modifier.fillMaxSize()) {
val navController = rememberNavController()
Scaffold(
content = {padding ->
Column(
modifier = Modifier.padding(padding)
) {
Navigation(navController = navController)
}
},
bottomBar = {
BottomNavigationBar(
items = listOf(
BottomNavItem(
name = "Home",
route = "home",
icon = Icons.Outlined.Home
),
BottomNavItem(
name = "Orders",
route = "orders",
icon = Icons.Outlined.ShoppingBag
),
BottomNavItem(
name = "Map",
route = "map",
icon = Icons.Outlined.Map
),
BottomNavItem(
name = "Profile",
route = "profile",
icon = Icons.Outlined.Person
),
),
navController = navController,
onItemClick = {
navController.navigate(it.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
}
)
}
}
}
}
}
BottomNav.kt
@Composable
fun Navigation (navController: NavHostController) {
NavHost(navController = navController, startDestination = "home" ) {
composable("home") {
HomeScreen()
}
composable("orders") {
OrdersScreen()
}
composable("map") {
MapScreen()
}
composable("profile") {
ProfileScreen()
}
composable("login") {
MapScreen()
}
}
}
What I've tried:
Inside my ProfileScreen() Composable I have
ClickableText(
AnnotatedString("Log In"),
onClick = {
})
But I can't navigate to login screen. I've tried something like this:
val navController = rememberNavController()
Navigation(navController)
ClickableText(
AnnotatedString("Log In"),
onClick = {
navController.navigate("login")
})
but it doesn't work as intended, because I have HomeScreen(start screen) on top of my ProfileScreen, and after clicking LogIn text I have this "temporary" MapScreen.
I know that I'm doing something wrong, but I've just started learning compose and I can't really understand navigation documentation for nested navigation, which as I suppose should be used here.
I've tried to make additional nav graph for Profile->login route, but I couldn't open Profile screen, because of lack of memory
Adding nested navigation as per documentation doesn't work att all in my case
If it helps, below is the beginning of ProfileScreen Composable, maybe I have to pass some argument there.
@Composable
fun ProfileScreen(viewModel: AuthenticationViewModel = androidx.lifecycle.viewmodel.compose.viewModel()) {
...
}
So after few days of struggle, I've managed to partially solve my issue with navigation, now I have to figure out how to remove bottom navigation bar and add back button or change bottom navigation behaviour after navigating to Login Screen, because after that navigation, "Profile" icon isn't selected and I can't go back to Profile Screen unless I press back button.
What I did to resolve this issue:
BottomNav.kt
@Composable
fun ProfileScreen(onItemClick: () -> Unit, // here I've added lambda function
viewModel: AuthenticationViewModel = androidx.lifecycle.viewmodel.compose.viewModel()) {...}
I've added simple button without styling etc to navigate:
Button(onClick = onItemClick) {
}
And the last thing, inside of Navigation function I've edited ProfileScreen composable:
@Composable
fun Navigation (navController: NavHostController) {
NavHost(navController = navController, startDestination = "home" ) {
composable("home") {
HomeScreen()
}
composable("orders") {
OrdersScreen()
}
composable("map") {
MapScreen()
}
// this was edited
composable("profile") {
ProfileScreen(onItemClick = {
navController.navigate("login")
})
}
composable("login") {
LoginScreen()
}
}
}