Jetpack Compose Navigation 中的参数传递

Jetpack Compose Navigation 中的参数传递

使用navController.navigate("xxx")时传递参数

简单的例子,不依赖xml布局文件中的 Activity 的 ID或,不使用Bundle,不使用NavOptions

在 Jetpack Compose 中,您可以使用导航组件中的 NavController 类在不同的屏幕之间导航。向目标传递参数类似于向 URL 添加查询参数或路径。

要将参数传递给目标屏幕,您需要向路由添加参数占位符。

例如,假设您有一个名为 DetailScreen 的屏幕,用于显示用户的详细信息,并且您希望在导航到此屏幕时将用户的ID作为参数传递。您可以将 DetailScreen 的路由定义为"detail/{uId}",其中 uId 是用户ID的占位符。

接收端:

kotlin 复制代码
@Composable
fun MyNavHost() {
    val navController = rememberNavController()

    NavHost(
        navController = navController,
        startDestination = "home"
    ) {
        composable("detail/{uId}") { navBackStackEntry ->
            /* 从路由中提取 id */
            val uId = navBackStackEntry.arguments?.getString("uId")
            /* 我们检查它是否不为空 */
            uId?.let { id->
                DetailScreen(uId = id)
            }
        }
        /* ... */
    }
}

传递对象:

请记住,您只能向您的目标传递字符串值。但是,如果您有一个数据类并希望将其传递给您的组合,则一个可能的解决方案是使用任何转换器将您的对象转换为字符串。

scss 复制代码
composable("detail/{user}") { navBackStackEntry ->
    // 创建 Gson 对象
    val gson: Gson = GsonBuilder().create()
    /* 从路由中提取用户对象的 JSON */
    val userJson = navBackStackEntry.arguments?.getString("user")
    // 将 JSON 字符串转换为 User 数据类对象
    val userObject = gson.fromJson(userJson, User::class.java)
    DetailScreen(user = userObject)
}

多个参数:

如果您想传递多个参数,则可以定义一个带有多个占位符的路由,这些占位符用斜杠("/")分隔。例如:

java 复制代码
composable("detail/{name}/{id}") { backStackEntry ->
    // 从路由中提取参数
    val name = backStackEntry.arguments?.getString("name")
    val id = backStackEntry.arguments?.getString("id")

    // 检查参数是否不为空,并渲染屏幕
    if (name != null && id != null) {
        DetailScreen(name, id)
    }
}

可选参数:

如果在某些情况下,您不希望有任何参数。那么,您也可以将其定义为可选参数。但是,要定义一个可选参数..

我们必须使用查询参数语法("?argName={argName}") 我们必须设置一个defaultValue,或者将nullability设置为true。

ini 复制代码
composable(
    route = "detail?uId={uId}",
    arguments = listOf(
        navArgument("uId") {
            defaultValue = 0
            type = NavType.IntType
        }
    )
) { navBackStackEntry ->
    /* 从路由中提取 id */
    val uId = navBackStackEntry.arguments?.getInt("uId")
    /* 检查是否为空 */
    uId?.let {
        DetailScreen(uId = it)
    }
}

注意

"如果您想要添加更多参数,在参数之间加上 & 符号,例如:"?argName1={argName1}&argName2={argName2}"

注意:您传递的字符串/ JSON 字符串值不应包含 "/",否则由于意外的路径/路由,您的应用程序将崩溃。"

发送端

kotlin 复制代码
@Composable
fun HomeScreen(navController: NavController) {
    Button(
        onClick = {
            /* 用 1 替换 {uId} */
            navController.navigate(
                "detail/{uId}" // 根据需要修改您的路由
                    .replace(
                        oldValue = "{uId}",
                        newValue = "1"
                    )
            )
        }
    ) {
        Text(text = "使用 id 1 导航到详情页面")
    }
}

传递对象

ini 复制代码
@Composable
fun HomeScreen(navController: NavController) {
    val userObj = User()
    Button(
        onClick = {   
            val gson: Gson = GsonBuilder().create()            
            val userJson = gson.toJson(userObj)
            /* 用 userJson 替换 {user} */
            navController.navigate(
                "detail/{user}" // 根据需要修改您的路由
                    .replace(
                        oldValue = "{user}",
                        newValue = userJson
                    )
            )
        }
    ) {
        Text(text = "使用 userJson 导航到详情页面")
    }
}

原文链接

谷歌上找的文章自己翻译的,仅供学习,如有侵权请联系我,我会进行修改或删除

相关推荐
xjt_09013 分钟前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
游戏开发爱好者815 分钟前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
我是伪码农15 分钟前
Vue 2.3
前端·javascript·vue.js
王码码203520 分钟前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
黑码哥36 分钟前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
夜郎king40 分钟前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
亓才孓1 小时前
[JDBC]元数据
android
独行soc1 小时前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能1 小时前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿1 小时前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市