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

Jetpack Compose中传递ImageUri至其他页面时为何发生变化?

Uri传递差异导致图片无法显示的问题分析与解决

问题原因

  • 直接将Uri对象拼接到导航路径时,Uri的toString()方法会自动解码特殊字符,把编码后的%3A还原成:。而导航组件解析参数时会再次解码,最终接收的Uri里%3A变成了:,和原始Uri格式不一致。
  • 拼接路由时末尾多了一个空格,也可能干扰参数的正常解析。

解决方法

方法1:手动编码Uri参数后传递

修改选图页面的导航代码,用Uri.encode()对Uri字符串进行编码,同时移除末尾多余的空格:

if (imageUri.path?.isNotEmpty() == true && doOnce) {
    println("choose "+imageUri)
    // 编码Uri字符串并移除末尾空格
    navHostController.navigate("${HealthScreen.HealthCreateNutritionScreen.route}?$CNPHOTO=${Uri.encode(imageUri.toString())}")
    doOnce = false
}

ViewModel里直接获取字符串即可,Navigation组件会自动完成解码,拿到的就是原始格式的Uri。

方法2:使用类型安全的Uri导航参数(更推荐)

利用Navigation的UriType参数类型,让组件自动处理编码解码逻辑,彻底避免手动拼接的错误:

  1. 修改导航图的参数定义:
composable(
    route = "${HealthScreen.HealthCreateNutritionScreen.route}?$CNPHOTO={$CNPHOTO}",
    arguments = listOf(
        navArgument(name = CNPHOTO) {
            type = NavType.UriType // 改为Uri类型
            defaultValue = Uri.EMPTY
        })
) {
    CreateNutritionRoute(navHostController = navHostController)
}
  1. 选图页面直接传递Uri对象:
navHostController.navigate("${HealthScreen.HealthCreateNutritionScreen.route}?$CNPHOTO=$imageUri")
  1. ViewModel里直接获取Uri类型:
init {
    val capturedImage = savedStateHandle.get<Uri>(CNPHOTO)
    println("viewmodel->"+capturedImage)
    capturedImage?.let {
        _state.update { state ->
            state.copy(image = it.toString())
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 17:52:22