我有一个带有 jetpack compose 的底部导航栏,但当我在它之间导航时,屏幕没有显示,它显示带有空白白页的底部栏
我有三个屏幕:主页、个人资料和设置
@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()
}
个人资料屏幕
@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()
}
设置屏幕
@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()
}
还有这个 BottomBarScreen 类
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
)
}
还有这个 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()
}
}
}
和这个主屏幕代码
@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)
}
}
最后,我在这里调用了 MainScreen Composable
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Surface(modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.surface
) {
MainScreen()
}
}
}
我认为您不理解
NavHost
的概念,它不仅仅是一个控制导航的函数,它还是一个 可组合,它的作用就像一个目的地的容器。
您的代码中的问题是,您在主可组合容器之外调用 BottomNavGraph
Scaffold
,因此即使您导航到屏幕,它也不会显示,因为 Scaffold
遮蔽了它。
你应该这样做:
@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)
}
}