Reputation: 2704
I have a bottomNavigtionBar with jetpack compose but the screens are not showing when I navigate between it, it's showing the bottom bar with a blank white page
I have three screens Home, Profile and Settings
@Composable
fun HomeThirdScreen() {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Blue),
contentAlignment = Alignment.Center
) {
Text(
text = "Home",
fontSize = MaterialTheme.typography.headlineLarge.fontSize,
fontWeight = FontWeight.Bold,
color = Color.White
)
}
}
@Preview
@Composable
fun PreviewHomeThirdScreen() {
HomeThirdScreen()
}
Profile Screen
@Composable
fun ProfileScreen() {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Magenta),
contentAlignment = Alignment.Center
) {
Text(
text = "Profile",
fontSize = MaterialTheme.typography.headlineLarge.fontSize,
fontWeight = FontWeight.Bold,
color = Color.White
)
}
}
@Preview
@Composable
fun PreviewProfileScreen() {
ProfileScreen()
}
Settings screen
@Composable
fun SettingsScreen() {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Gray),
contentAlignment = Alignment.Center
) {
Text(
text = "Settings",
fontSize = MaterialTheme.typography.headlineLarge.fontSize,
fontWeight = FontWeight.Bold,
color = Color.White
)
}
}
@Preview
@Composable
fun PreviewSettingsScreen() {
SettingsScreen()
}
and this BottomBarScreen class
sealed class BottomBarScreen(
val route:String,
val title:String,
val icon:ImageVector
){
object Home:BottomBarScreen(
route = "home",
title = "Home",
icon = Icons.Default.Home
)
object Profile:BottomBarScreen(
route = "profile",
title = "Profile",
icon = Icons.Default.AccountCircle
)
object Settings:BottomBarScreen(
route = "settings",
title = "Settings",
icon = Icons.Default.Settings
)
}
and this BottomNavGraph
@Composable
fun BottomNavGraph(navHostController: NavHostController) {
NavHost(navController = navHostController, startDestination = BottomBarScreen.Home.route){
composable(route = BottomBarScreen.Home.route){
HomeThirdScreen()
}
composable(route = BottomBarScreen.Profile.route){
ProfileScreen()
}
composable(route = BottomBarScreen.Settings.route){
SettingsScreen()
}
}
}
and this main screen code
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen() {
val navHostController = rememberNavController()
BottomNavGraph(navHostController = navHostController)
val screens = listOf(
BottomBarScreen.Home,
BottomBarScreen.Profile,
BottomBarScreen.Settings
)
val navBackStackEntry by navHostController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
var selectedItemIndex by rememberSaveable {
mutableIntStateOf(0)
}
Scaffold(
bottomBar = {
NavigationBar {
screens.forEachIndexed { index, bottomBarScreen ->
NavigationBarItem(selected = currentDestination?.hierarchy?.any {
it.route == bottomBarScreen.route } == true,
label = { Text(text = bottomBarScreen.title) },
onClick = {
selectedItemIndex = index
navHostController.navigate(bottomBarScreen.route)
},
icon = {
Icon(
imageVector = bottomBarScreen.icon,
contentDescription = bottomBarScreen.title
)
})
}
}
}) {
it.calculateTopPadding()
it.calculateBottomPadding()
it.calculateEndPadding(LayoutDirection.Ltr)
it.calculateStartPadding(LayoutDirection.Ltr)
}
}
and finally, I called the MainScreen Composable here
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Surface(modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.surface
) {
MainScreen()
}
}
}
Upvotes: 0
Views: 104
Reputation: 1150
I don't think you understand the concept of a NavHost
it's not just a function that controls navigation its also a composable that acts like a container o for it's destinations.
The problem in your code is that you are calling BottomNavGraph
outside your main composable container in your case Scaffold
so even though you are navigating to the screen it will not show because of the Scaffold
shadowing it.
You should do it like this:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen() {
val navHostController = rememberNavController()
val screens = listOf(
BottomBarScreen.Home,
BottomBarScreen.Profile,
BottomBarScreen.Settings
)
val navBackStackEntry by navHostController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
var selectedItemIndex by rememberSaveable {
mutableIntStateOf(0)
}
Scaffold(
bottomBar = {
NavigationBar {
screens.forEachIndexed { index, bottomBarScreen ->
NavigationBarItem(selected = currentDestination?.hierarchy?.any {
it.route == bottomBarScreen.route } == true,
label = { Text(text = bottomBarScreen.title) },
onClick = {
selectedItemIndex = index
navHostController.navigate(bottomBarScreen.route)
},
icon = {
Icon(
imageVector = bottomBarScreen.icon,
contentDescription = bottomBarScreen.title
)
})
}
}
}) {
it.calculateTopPadding()
it.calculateBottomPadding()
it.calculateEndPadding(LayoutDirection.Ltr)
it.calculateStartPadding(LayoutDirection.Ltr)
BottomNavGraph(navHostController = navHostController)
}
}
Upvotes: 1