Jetpack Compose - 导航 - 脚手架 + NavHost 不工作
Jetpack Compose - Navigation - Scaffold + NavHost not working
-
android
-
android-jetpack
-
android-jetpack-navigation
-
android-jetpack-compose
-
android-jetpack-compose-scaffold
所以我正在尝试使用 Jetpack Compose 创建一个应用程序。我有一个屏幕功能,其中包含一个没有顶部应用栏的脚手架、一个用于导航的底部栏和一个设置在底部栏中的浮动操作按钮。这一切都很好。
但是,当我将 NavHost 添加到脚手架的内容时,整个事情都停止了。没有 NavHost 一切正常,只是内容是屏幕的可组合功能。我尝试过为 NavHost 使用不同数量的可组合位置,不同的填充值都无济于事。
What it looks like without a NavHost (i.e. how I want it to look)
代码:
sealed class Screen(val route: String, @DrawableRes val iconId: Int){
object Home : Screen("home", R.drawable.ic_home_24px)
object Stats : Screen("stats", R.drawable.ic_stats_icon)
object Add : Screen("add", R.drawable.ic_add_24px)
object Programs : Screen("programs", R.drawable.ic_programs_icon)
object Exercises : Screen("exercises", R.drawable.ic_exercises_icon)
}
@ExperimentalFoundationApi
@Preview
@Composable
fun Screen(){
val navController = rememberNavController()
Scaffold(
backgroundColor = OffWhite,
bottomBar = {
BottomBar(navController = navController)
},
floatingActionButton = {
FloatingActionButton(
onClick = {},
shape = CircleShape,
backgroundColor = Blue
) {
Icon(
painter = painterResource(id = R.drawable.ic_add_24px),
contentDescription = "Add",
tint = OffWhite,
modifier = Modifier
.padding(12.dp)
.size(32.dp)
)
}
},
isFloatingActionButtonDocked = true,
floatingActionButtonPosition = FabPosition.Center,
) {
HomeScreen()
// NavHost(
// navController = navController,
// startDestination = Screen.Home.route
// ){
// composable(Screen.Home.route){ HomeScreen() }
// composable(Screen.Stats.route){ HomeScreen() }
// composable(Screen.Programs.route){ HomeScreen() }
// composable(Screen.Exercises.route){ HomeScreen() }
// }
}
}
@Composable
fun BottomBar(
navController : NavController
){
val items = listOf(
Screen.Home,
Screen.Stats,
Screen.Add,
Screen.Programs,
Screen.Exercises
)
BottomAppBar(
backgroundColor = OffWhite,
cutoutShape = CircleShape,
content = {
BottomNavigation(
backgroundColor = OffWhite,
contentColor = OffWhite,
modifier = Modifier
.height(100.dp)
) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
items.forEach { screen ->
val selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true
BottomNavigationItem(
icon = {
val iconSize = if (selected) 32.dp else 20.dp
Icon(
painter = painterResource(id = screen.iconId),
contentDescription = screen.route,
tint = Blue,
modifier = Modifier
.padding(12.dp)
.size(iconSize)
)
},
selected = selected,
onClick = {
//Navigate to selected screen
navController.navigate(screen.route) {
//Pop all from stack
popUpTo(navController.graph.findStartDestination().id){
saveState = true
}
//Avoid multiple copies of same screen on stack
launchSingleTop = true
//Restore state when reselecting a previously selected item
restoreState = true
}
},
alwaysShowLabel = false
)
}
}
}
)
}
What it looks like with the NavHost. 该图像中的框是未能绘制的 BottomBar,因为可以单击每个框将我带到 BottomBar、BottomNavigationItem、Icon 等。任何人都知道这里发生了什么,并且我能做些什么来解决它?谢谢
编辑:我想到的一件事是将有趣的 BottomBar -> BottomNavigationItem 中的 'selected' 布尔值更改为始终为真,只是为了查看空值是否影响它,但这并没有改变任何东西。
原来我的工作室主题隐藏了错误通知。更改主题后显示
java.lang.IllegalStateException: ViewModels creation is not supported in Preview
所以我想我需要在我的 phone 中重击它来测试。
错误消息说 Preview 不支持创建 ViewModels。因为,NavHost
创建视图模型,所以错误。所以我做了一些预览脚手架和一些屏幕的事情,我把脚手架的内容分开了。
示例:
@Composable
fun MainApp(
navController: NavController,
content: @Composable (PaddingValues) -> Unit
) {
StoreTheme {
Scaffold(
bottomBar = { BottomAppNavigationBar(navController) },
content = content
)
}
}
在真实应用程序上:
...
val navController = rememberNavController()
MainApp(navController) { innerPadding ->
NavHost(
navController = navController,
startDestination = BottomNavMenu.Screen1.route,
modifier = Modifier.padding(innerPadding)
) {
composable(...) { Screen1... }
composable(...) { Screen2... }
}
}
...
预览中:
@Preview(showBackground = true)
@Composable
fun MainAppPreview() {
val navController = rememberNavController()
MainApp(navController) {
Screen1(navController)
}
}
android
android-jetpack
android-jetpack-navigation
android-jetpack-compose
android-jetpack-compose-scaffold
所以我正在尝试使用 Jetpack Compose 创建一个应用程序。我有一个屏幕功能,其中包含一个没有顶部应用栏的脚手架、一个用于导航的底部栏和一个设置在底部栏中的浮动操作按钮。这一切都很好。
但是,当我将 NavHost 添加到脚手架的内容时,整个事情都停止了。没有 NavHost 一切正常,只是内容是屏幕的可组合功能。我尝试过为 NavHost 使用不同数量的可组合位置,不同的填充值都无济于事。
What it looks like without a NavHost (i.e. how I want it to look)
代码:
sealed class Screen(val route: String, @DrawableRes val iconId: Int){
object Home : Screen("home", R.drawable.ic_home_24px)
object Stats : Screen("stats", R.drawable.ic_stats_icon)
object Add : Screen("add", R.drawable.ic_add_24px)
object Programs : Screen("programs", R.drawable.ic_programs_icon)
object Exercises : Screen("exercises", R.drawable.ic_exercises_icon)
}
@ExperimentalFoundationApi
@Preview
@Composable
fun Screen(){
val navController = rememberNavController()
Scaffold(
backgroundColor = OffWhite,
bottomBar = {
BottomBar(navController = navController)
},
floatingActionButton = {
FloatingActionButton(
onClick = {},
shape = CircleShape,
backgroundColor = Blue
) {
Icon(
painter = painterResource(id = R.drawable.ic_add_24px),
contentDescription = "Add",
tint = OffWhite,
modifier = Modifier
.padding(12.dp)
.size(32.dp)
)
}
},
isFloatingActionButtonDocked = true,
floatingActionButtonPosition = FabPosition.Center,
) {
HomeScreen()
// NavHost(
// navController = navController,
// startDestination = Screen.Home.route
// ){
// composable(Screen.Home.route){ HomeScreen() }
// composable(Screen.Stats.route){ HomeScreen() }
// composable(Screen.Programs.route){ HomeScreen() }
// composable(Screen.Exercises.route){ HomeScreen() }
// }
}
}
@Composable
fun BottomBar(
navController : NavController
){
val items = listOf(
Screen.Home,
Screen.Stats,
Screen.Add,
Screen.Programs,
Screen.Exercises
)
BottomAppBar(
backgroundColor = OffWhite,
cutoutShape = CircleShape,
content = {
BottomNavigation(
backgroundColor = OffWhite,
contentColor = OffWhite,
modifier = Modifier
.height(100.dp)
) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
items.forEach { screen ->
val selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true
BottomNavigationItem(
icon = {
val iconSize = if (selected) 32.dp else 20.dp
Icon(
painter = painterResource(id = screen.iconId),
contentDescription = screen.route,
tint = Blue,
modifier = Modifier
.padding(12.dp)
.size(iconSize)
)
},
selected = selected,
onClick = {
//Navigate to selected screen
navController.navigate(screen.route) {
//Pop all from stack
popUpTo(navController.graph.findStartDestination().id){
saveState = true
}
//Avoid multiple copies of same screen on stack
launchSingleTop = true
//Restore state when reselecting a previously selected item
restoreState = true
}
},
alwaysShowLabel = false
)
}
}
}
)
}
What it looks like with the NavHost. 该图像中的框是未能绘制的 BottomBar,因为可以单击每个框将我带到 BottomBar、BottomNavigationItem、Icon 等。任何人都知道这里发生了什么,并且我能做些什么来解决它?谢谢
编辑:我想到的一件事是将有趣的 BottomBar -> BottomNavigationItem 中的 'selected' 布尔值更改为始终为真,只是为了查看空值是否影响它,但这并没有改变任何东西。
原来我的工作室主题隐藏了错误通知。更改主题后显示
java.lang.IllegalStateException: ViewModels creation is not supported in Preview
所以我想我需要在我的 phone 中重击它来测试。
错误消息说 Preview 不支持创建 ViewModels。因为,NavHost
创建视图模型,所以错误。所以我做了一些预览脚手架和一些屏幕的事情,我把脚手架的内容分开了。
示例:
@Composable
fun MainApp(
navController: NavController,
content: @Composable (PaddingValues) -> Unit
) {
StoreTheme {
Scaffold(
bottomBar = { BottomAppNavigationBar(navController) },
content = content
)
}
}
在真实应用程序上:
...
val navController = rememberNavController()
MainApp(navController) { innerPadding ->
NavHost(
navController = navController,
startDestination = BottomNavMenu.Screen1.route,
modifier = Modifier.padding(innerPadding)
) {
composable(...) { Screen1... }
composable(...) { Screen2... }
}
}
...
预览中:
@Preview(showBackground = true)
@Composable
fun MainAppPreview() {
val navController = rememberNavController()
MainApp(navController) {
Screen1(navController)
}
}