android - 将底部导航栏与 Jetpack Compose 结合使用的正确策略

标签 android android-jetpack-compose android-jetpack-navigation

Compose Navigation 组件的官方文档建议我们应该通过在 Scaffold 中添加 NavHost 来创建一个 Navigation 组件。

参见https://developer.android.com/jetpack/compose/navigation#bottom-nav

我使用这种方法的问题是,使用这种方法底部导航栏将在所有屏幕中可见。我希望它仅在底部栏项目中存在的屏幕中可见。

添加底部栏的第二种方法是不在 Scaffold 内添加 NavHost。相反,在目标之一中添加底部栏,然后根据选择的索引隐藏/显示支架主体中的可组合项。

var selectedBottomBarIndex by remember {
    mutableStateOf(0)
}

Scaffold(
    bottomBar = {
            MyBottomBar(currentIndex = selectedBottomBarIndex, onChanged = {
                    selectedBottomBarIndex = it
                }
            )
    } {
    when (selectedBottomBarIndex) {        
        0 -> HomeScreen(navController)
        1 -> AssignmentHomeScreen(navController)
        2 -> CategoryScreen(navController)
        else -> ProfileHomeScreen(navController)
    }
}

我只是想知道这两种添加底部导航的方法有何优缺点。 这是在生产应用程序中安全使用的第二种方法。

最佳答案

以下是如何实现它的示例。

@Composable
fun JourneyApp() {
    JourneyTheme {
        val navController = rememberNavController()
        val onBack: () -> Unit = {
            navController.popBackStack()
        }
        val screens = listOf(
            Screen.Home,
            Screen.Collections,
            Screen.UserProfile
        )
        val showBottomBar = navController
            .currentBackStackEntryAsState().value?.destination?.route in screens.map { it.route }
        // https://developer.android.com/jetpack/compose/navigation
        Scaffold(
            bottomBar = {
                if (showBottomBar) {
                    BottomNavigation {
                        val navBackStackEntry by navController.currentBackStackEntryAsState()
                        val currentDestination = navBackStackEntry?.destination
                        screens.forEach { screen ->
                            BottomNavigationItem(
                                icon = { Icon(imageVector = screen.icon, contentDescription = screen.label) },
                                label = { Text(screen.label) },
                                selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
                                onClick = {
                                    navController.navigate(screen.route) {
                                        // Pop up to the start destination of the graph to
                                        // avoid building up a large stack of destinations
                                        // on the back stack as users select items
                                        popUpTo(navController.graph.findStartDestination().id) {
                                            saveState = true
                                        }
                                        // Avoid multiple copies of the same destination when
                                        // reselecting the same item
                                        launchSingleTop = true
                                        // Restore state when reselecting a previously selected item
                                        restoreState = true
                                    }
                                }
                            )
                        }
                    }
                }
            }
        ) { innerPadding ->
            Box(modifier = Modifier.padding(innerPadding)) {
                // nav graph
                NavHost(navController = navController, startDestination = Screen.Home.route) {
                    // add new navigation function
                    composable(Screen.Home.route) { HomeScreen(navigateToImportPhoto = { navController.navigate("importPhoto") }) }
                    composable(Screen.Collections.route) { CollectionsScreen() }
                    composable(Screen.UserProfile.route) { UserProfileScreen() }
                    // new screen, not part of bottom nav
                    composable("importPhoto") { ImportPhotoScreen(onBack = onBack) }
                }
            }
        }
    }
}

关于android - 将底部导航栏与 Jetpack Compose 结合使用的正确策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76835709/

相关文章:

android - InAppBillingService 绑定(bind)失败

Android:如何将 <string> 元素注入(inject)到 XML 中的另一个 <string> 元素中?

android - 如何在 Constraint Layout Compose 中使用偏差

android - 如何在 Jetpack 撰写中将 Canvas 中的文本居中?

android - 视频监听器正在运行

android - 如何将滚动添加到 Android 布局?

android - 如何优化 JetPack Compose 列表性能?

android - 如何在点击 FAB 时启动新的导航图?

android-architecture-components - 在导航组件的起始目标位置时如何处理后退按钮

android - 如何将协程范围限定为 fragment ,以便在 fragment 离开屏幕或被销毁时自动取消?