Jetpack Compose - Навигация - Scaffold + NavHost не работает

поэтому я пытаюсь создать приложение с помощью Jetpack Compose. У меня есть функция Screen, которая содержит Scaffold без верхней панели приложения, нижнюю панель для навигации и кнопку с плавающим действием, установленную в нижней панели. Все работает нормально.

Однако, когда я добавляю 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, который не отображается, так как каждое поле можно щелкнуть, что приведет меня к BottomBar, BottomNavigationItem, Icon и т. Д. Кто-нибудь имеет представление о том, что здесь происходит, и что я могу сделать, чтобы это исправить? Спасибо

Изменить: одна вещь, о которой я подумал, - это изменить логическое значение selected в fun BottomBar -> BottomNavigationItem, чтобы оно всегда было истинным, просто чтобы увидеть, влияют ли на него нулевые значения, но это ничего не изменило.

2 ответа

Решение

Оказывается, моя студийная тема скрывала уведомление об ошибке. После смены темы он говорит

java.lang.IllegalStateException: создание ViewModels не поддерживается в предварительном просмотре

так что я думаю, мне нужно ударить его в моем телефоне, чтобы проверить.

В сообщении об ошибке говорится, что предварительный просмотр не поддерживает создание моделей просмотра . С, NavHostсоздать viewmodels, делает ли ошибку. Итак, что я сделал для предварительного просмотра каркаса и некоторого экрана, я разделил содержимое каркаса.

Пример:

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