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参数类型,让组件自动处理编码解码逻辑,彻底避免手动拼接的错误:
- 修改导航图的参数定义:
composable( route = "${HealthScreen.HealthCreateNutritionScreen.route}?$CNPHOTO={$CNPHOTO}", arguments = listOf( navArgument(name = CNPHOTO) { type = NavType.UriType // 改为Uri类型 defaultValue = Uri.EMPTY }) ) { CreateNutritionRoute(navHostController = navHostController) }
- 选图页面直接传递Uri对象:
navHostController.navigate("${HealthScreen.HealthCreateNutritionScreen.route}?$CNPHOTO=$imageUri")
- 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
相关产品推荐
相关产品推荐

