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

Jetpack Compose中BottomNavigationItem间如何传递页面参数?

Jetpack Compose中BottomNavigationItem间如何传递页面参数?

嘿,这个问题我之前也碰到过,其实调整一下路由和导航逻辑就能搞定,我给你一步步拆解:

1. 先定义带参数占位符的路由

首先,你需要给需要接收参数的页面路由添加参数占位符,比如如果要传一个itemId参数,路由可以写成"detail/{itemId}"(必填参数)或者"detail?itemId={itemId}"(可选参数)。

假设你的底部导航项是用数据类定义的,那可以这样设置:

data class BottomNavItem(
    val route: String,
    val icon: Int,
    val label: String
)

// 示例列表,其中详情页路由先写基础标识,跳转时再拼接参数
val items = listOf(
    BottomNavItem("home", R.drawable.ic_home, "首页"),
    BottomNavItem("detail", R.drawable.ic_detail, "详情")
)

2. 修改BottomNavigationItem的跳转逻辑

在onClick回调里,不要直接用item.route跳转,而是根据路由类型动态拼接参数。比如给详情页传递itemId=123:

BottomNavigation(
    backgroundColor = colorResource(id = R.color.grey),
    contentColor = Color.Black
) {
    items.forEach { item ->
        BottomNavigationItem(
            icon = { Icon(painterResource(id = item.icon), contentDescription = item.label) },
            selectedContentColor = colorResource(id = R.color.yellow),
            unselectedContentColor = colorResource(id = R.color.white),
            alwaysShowLabel = true,
            selected = currentRoute == item.route,
            onClick = {
                // 动态拼接带参数的路由
                val targetRoute = when (item.route) {
                    "detail" -> "detail/123" // 这里替换成你实际的参数值,也可以从外部变量获取
                    else -> item.route
                }
                navController.navigate(targetRoute) {
                    navController.graph.startDestinationRoute?.let { screen_route ->
                        popUpTo(screen_route) {
                            saveState = true
                        }
                    }
                    launchSingleTop = true
                    restoreState = true
                }
            }
        )
    }
}

3. 在目标页面接收参数

接下来在接收参数的页面,通过NavBackStackEntry获取传递过来的参数:

@Composable
fun DetailScreen(navController: NavHostController) {
    // 获取必填参数
    val itemId = navController.currentBackStackEntry?.arguments?.getString("itemId")
    // 如果是Int类型参数,用getInt:
    // val itemId = navController.currentBackStackEntry?.arguments?.getInt("itemId")

    // 用参数做业务逻辑
    Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "当前选中的Item ID: $itemId")
    }
}

4. 在导航图中声明参数(关键步骤)

最后要在NavHost的导航图里,给带参数的目的地声明参数规则,这样Navigation组件才能正确解析参数:

NavHost(navController = navController, startDestination = "home") {
    composable("home") { HomeScreen() }
    // 声明带必填参数的目的地
    composable(route = "detail/{itemId}") { backStackEntry ->
        val itemId = backStackEntry.arguments?.getString("itemId")
        DetailScreen(navController = navController)
    }

    // 如果是可选参数,这样定义:
    /*
    composable(
        route = "detail?itemId={itemId}",
        arguments = listOf(
            navArgument("itemId") {
                type = NavType.StringType
                defaultValue = "default_001" // 设置默认值
                nullable = true
            }
        )
    ) { backStackEntry ->
        val itemId = backStackEntry.arguments?.getString("itemId")
        DetailScreen(navController = navController)
    }
    */
}

这样就能顺利在BottomNavigationItem跳转时传递参数啦,要是你有更复杂的参数类型(比如自定义对象),还可以用NavType.ParcelableType来处理,不过基础的字符串、数字参数用上面的方法就足够了。

备注:内容来源于stack exchange,提问作者Alex20280

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 10:33:05