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

如何在Jetpack Compose中创建横向类NavigationRail的自定义BottomNavigationBar

实现类似Windows 7任务栏的横向底部导航栏

需求说明:

  • 打造一款类似Windows 7底部任务栏的自定义底部导航栏,功能与NavigationRail一致,但采用横向布局
  • 所有导航项从左侧开始排列,项之间的间距支持自定义(例如16.dp)
  • 目标效果:导航项全部靠左对齐,每个项保持设定的间距,整体固定在屏幕底部

我曾尝试通过自定义RowScope结合NavigationBar实现,但未达到预期效果,相关代码如下:

@Composable
fun CustomRowScope(
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    // 创建带自定义配置的Row
    Row(
        horizontalArrangement = Arrangement.spacedBy(8.dp),
        modifier = modifier.padding(16.dp),
        content = content
    )
}

@Composable
fun MyNavigationBar(
    modifier: Modifier,
//    state: MutableState<Boolean>,
    //navController: NavController,
    onNavItemClick: (route: String) -> Unit
) {
    //val backStackEntry by navController.currentBackStackEntryAsState()
    //val currentRoute = backStackEntry?.destination?.route

    NavigationBar(
        modifier = modifier,
        content = {
            CustomRowScope(modifier = Modifier) {

                bottomNavItems.forEach { item ->
                    //val selected = item.route == backStackEntry?.destination?.route

                    NavigationBarItem(
                        selected = false,//selected,
                        onClick = { onNavItemClick(item.route) },

                        icon = {
                            Icon(
                                imageVector = item.icon,
                                contentDescription = "${item.name} Icon",
                            )
                        }
                    )
                }
            }
        }
    )
} 

解决方案

问题出在嵌套了自定义RowScope,NavigationBar的content参数本身就是RowScope类型,直接在这个作用域内配置排列规则即可,无需额外嵌套Row。

修正后的完整实现代码:

// 定义导航项数据类
data class BottomNavItem(
    val name: String,
    val route: String,
    val icon: ImageVector
)

// 示例导航项列表
val bottomNavItems = listOf(
    BottomNavItem("主页", "home", Icons.Filled.Home),
    BottomNavItem("文档", "docs", Icons.Filled.Description),
    BottomNavItem("设置", "settings", Icons.Filled.Settings)
)

@Composable
fun WindowsStyleBottomNavBar(
    modifier: Modifier = Modifier,
    selectedRoute: String,
    onNavItemClick: (route: String) -> Unit,
    itemSpacing: Dp = 16.dp
) {
    NavigationBar(modifier = modifier) {
        // 直接在NavigationBar的RowScope中配置排列规则
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.spacedBy(itemSpacing, Alignment.Start),
            verticalAlignment = Alignment.CenterVertically
        ) {
            bottomNavItems.forEach { item ->
                val isSelected = item.route == selectedRoute
                NavigationBarItem(
                    selected = isSelected,
                    onClick = { onNavItemClick(item.route) },
                    icon = {
                        Icon(
                            imageVector = item.icon,
                            contentDescription = "${item.name} 图标"
                        )
                    },
                    label = { Text(item.name) } // 可选:显示导航项文字
                )
            }
        }
    }
}

// 使用示例
@Composable
fun MainScreen() {
    var selectedRoute by remember { mutableStateOf("home") }
    Scaffold(
        bottomBar = {
            WindowsStyleBottomNavBar(
                selectedRoute = selectedRoute,
                onNavItemClick = { selectedRoute = it },
                itemSpacing = 16.dp
            )
        }
    ) { paddingValues ->
        // 主内容区域
        Box(modifier = Modifier.padding(paddingValues)) {
            // 根据selectedRoute显示对应页面
        }
    }
}

关键说明

  1. 布局控制:直接在NavigationBar的RowScope中使用Row,通过Arrangement.spacedBy(itemSpacing, Alignment.Start)实现导航项左对齐且自定义间距
  2. 样式兼容:NavigationBarItem直接放在NavigationBar的作用域内,能够正确继承NavigationBar的默认样式(如选中状态的颜色、高度等)
  3. 可配置性:通过itemSpacing参数支持自定义项间距,满足不同布局需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 10:57:44