You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio Kotlin:侧边导航抽屉与底部导航栏共存问题求助

解决Jetpack Compose中Navigation Drawer与Bottom Navigation Bar共存问题

你代码的核心问题是使用了两个独立的Scaffold组件,导致TopAppBar所在容器和BottomBar所在容器互相覆盖,无法同时正常工作。只需将TopAppBar、BottomBar和页面内容整合到同一个Scaffold中,再用ModalNavigationDrawer包裹即可解决问题,修改后的完整代码如下:

data class NavigationItem(
    val title: String,
    val selectedIcon: ImageVector,
    val unselectedIcon: ImageVector,
    val badgeCount: Int? = null
)

@OptIn(ExperimentalMaterial3Api::class)
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            BlancheTheme {
                val items = listOf(
                    NavigationItem(
                        title = "Home",
                        selectedIcon = Icons.Filled.Home,
                        unselectedIcon = Icons.Outlined.Home
                    ),
                    NavigationItem(
                        title = "Orders",
                        selectedIcon = Icons.Filled.List,
                        unselectedIcon = Icons.Filled.List
                    ),
                    NavigationItem(
                        title = "Foto's",
                        selectedIcon = Icons.Filled.Add,
                        unselectedIcon = Icons.Outlined.Add
                    ),
                    NavigationItem(
                        title = "Prijzen",
                        selectedIcon = Icons.Filled.Create,
                        unselectedIcon = Icons.Filled.Create
                    ),
                )
                var selectedItemIndex by rememberSaveable {
                    mutableStateOf(0)
                }
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
                    val scope = rememberCoroutineScope()
                    
                    ModalNavigationDrawer(
                        drawerContent = {
                            ModalDrawerSheet {
                                items.forEachIndexed { index, item ->
                                    NavigationDrawerItem(
                                        label = { Text(text = item.title) },
                                        selected = index == selectedItemIndex,
                                        onClick = {
                                            selectedItemIndex = index
                                            scope.launch { drawerState.close() }
                                        },
                                        icon = {
                                            Icon(
                                                imageVector = if (index == selectedItemIndex) item.selectedIcon else item.unselectedIcon,
                                                contentDescription = item.title
                                            )
                                        }
                                    )
                                }
                            }
                        },
                        drawerState = drawerState
                    ) {
                        // 合并为单个Scaffold,同时配置topBar和bottomBar
                        Scaffold(
                            topBar = {
                                TopAppBar(
                                    title = { Text(text = "Blanche") },
                                    navigationIcon = {
                                        IconButton(onClick = {
                                            scope.launch { drawerState.open() }
                                        }) {
                                            Icon(
                                                imageVector = Icons.Default.Menu,
                                                contentDescription = "Menu"
                                            )
                                        }
                                    }
                                )
                            },
                            bottomBar = {
                                NavigationBar {
                                    items.forEachIndexed { index, item ->
                                        NavigationBarItem(
                                            selected = selectedItemIndex == index,
                                            onClick = { selectedItemIndex = index },
                                            label = { Text(text = item.title) },
                                            icon = {
                                                BadgedBox(
                                                    badge = {
                                                        item.badgeCount?.let {
                                                            Badge { Text(it.toString()) }
                                                        }
                                                    }
                                                ) {
                                                    Icon(
                                                        imageVector = if (index == selectedItemIndex) item.selectedIcon else item.unselectedIcon,
                                                        contentDescription = item.title
                                                    )
                                                }
                                            }
                                        )
                                    }
                                }
                            }
                        ) { paddingValues ->
                            // 页面内容区域,使用paddingValues避免被TopBar和BottomBar遮挡
                            Box(
                                modifier = Modifier
                                    .fillMaxSize()
                                    .padding(paddingValues),
                                contentAlignment = Alignment.Center
                            ) {
                                Text(text = "当前页面: ${items[selectedItemIndex].title}")
                            }
                        }
                    }
                }
            }
        }
    }
}

关键修改说明

  • 合并Scaffold:将原本分开的两个Scaffold合并为一个,同时传入topBar和bottomBar参数,确保两个导航组件属于同一个页面容器
  • 内容区域padding:使用Scaffold回调返回的paddingValues给内容区域设置padding,避免页面内容被TopAppBar和NavigationBar遮挡
  • 统一状态管理:侧边抽屉和底部导航栏共享同一个selectedItemIndex状态,确保选中状态同步,交互逻辑一致

内容的提问来源于stack exchange,提问作者UwUs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 11:10:34