当前位置: 首页 > 知识库问答 >
问题:

Jetpack撰写-导航-脚手架NavHost不工作

居琛
2023-03-14

所以我试图用Jetpack Compose创建一个应用程序。我有一个屏幕功能,它包含一个没有顶部应用程序栏的脚手架,一个用于导航的底部栏和一个设置在底部栏中的浮动操作按钮。这一切都很好。

但是,当我将NavHost添加到脚手架的内容时,整个事情就停止了工作。没有NavHost,一切都很好,只是内容是屏幕的可组合功能。我尝试了不同数量的NavHost可组合位置,不同的填充值都无济于事。

没有NavHost它看起来像什么(即我希望它看起来如何)

代码:

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
                    )
                }
            }
        }
    )
}

它与NavHost的样子。该图像中的框是无法绘制的底部栏,因为可以单击每个框,这将我带到底部栏,底部导航项目,图标等。任何人都知道这里发生了什么,我能做些什么来解决这个问题?谢谢

编辑:我想到的一件事是在有趣的BottomBar中更改“选定”布尔值-

共有2个答案

施慈
2023-03-14

事实证明,我的工作室主题隐藏了错误通知。更改主题后,它说

java.lang.IllegalStateException:预览版不支持创建 ViewModels

所以我想我需要在手机中敲打它来测试。

常雪风
2023-03-14

错误消息显示预览不支持视图模型创建。由于NavHost创建视图模型,因此会出错。因此,我所做的是在某种程度上预览脚手架和一些屏幕,我将脚手架的内容分开。

例:

@Composable
fun MainApp(
    navController: NavController,
    content: @Composable (PaddingValues) -> Unit
) {
    StoreTheme {
        Scaffold(
            bottomBar = { BottomAppNavigationBar(navController) },
            content = content
        )
    }
}

在Real App上:

...

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)
    }
}
 类似资料:
  • 正如你所看到的,这就是我用MaterialBottomNavigation实现NavHost的方式,我在消息和提要屏幕上都有很多项目,当我在它们两个屏幕之间导航时,它们会自动重构,但我不想这样做,因为那里有很多数据,它在导航时闪烁和fps下降到10以下,我试图在NavHost之前初始化数据viewModels,但结果仍然相同, 有没有办法一次组成屏幕,并在viewModels数据更新时更新它们?

  • 这是我的导航主机 我从主屏幕到“开始”屏幕很幼稚,但没有从“开始”导航到“计时器”屏幕,我已经传递了与从主屏幕获得的相同的ID。 这个主要可组合的 开始屏幕 当我点击按钮时,应用程序崩溃,错误如下

  • 我在脚手架下添加了自定义顶栏视图。我如何实现TopBar的以下行为,它是Jetpack compose android中脚手架的一部分。(如果无法扩展,则至少隐藏部分) 谢谢你

  • 我在一个应用程序上使用jetpack comuse实现了登录、注册。我将登录用户重定向到主屏幕,并让新用户保持在登录屏幕上。但问题是当我将用户从登录屏幕重定向到主屏幕,用户按下返回按钮时,登录屏幕就会出现。现在我知道这是导航组件的正常行为,但我需要更改它。我如何做到这一点? 使用此行从登录屏幕导航到主屏幕

  • 我有一个关于底部导航栏的奇怪问题,虽然我花了大量时间在它上面,但我无法解决。当我以“推荐”的方式(从许多教程中)使用它时,它就是无法导航。 那么,我所说的“推荐”方式是什么意思呢:我有一个单独的acticity,其中有一个名为“MainActivity”的navHostFragment。这个主要活动有一个XML布局文件,我将底部导航栏放在其中。BottomNavigationBar还有一个XML布

  • 如何在JetPack Compose BottomSheet状态更改上实现回调/侦听器机制? 类似的东西: 正如我们过去在Java/静态编程语言中所做的那样。 现在,我正在将其作为lambda传递给另一个需要关闭底片的可组合。 但是我想得到一个回调,底部的工作表已经完全折叠,我可以继续我的任务。 我面临的实际问题:我正在通过按钮单击将可组合文件转换为位图。按钮在BottomSheet内部,需要转换