提问人:NewPartizal 提问时间:9/20/2023 更新时间:9/20/2023 访问量:31
为什么当我在 jetpack compose 中将参数作为参数传递到另一个屏幕时,我的 imageUri 会发生变化?
Why my imageUri change when I pass as a argument to another screen in jetpack compose?
问:
我有一个屏幕用于从图库中选择照片,在此屏幕上,我从图库中选择照片,并将我选择的 imageUri 传输到我要显示的屏幕。因此,我们可以将其视为上一个屏幕,但是我选择的 imageUri 和我传递的 imageUri 之间存在差异。我的代码如下
这是我从图库屏幕中选择的图像
@Composable
fun CNChooseImageScreen(
navHostController: NavHostController
) {
var imageUri by remember { mutableStateOf<Uri>(Uri.EMPTY) }
val launcher = rememberLauncherForActivityResult(contract = ActivityResultContracts.GetContent()
) { uri: Uri? ->
if (uri != null) {
imageUri = uri
}else{
//if occurs error
navHostController.navigate(HealthScreen.HealthCreateNutritionScreen.route)
}
}
LaunchedEffect(Unit) {
launcher.launch("image/*")
}
var doOnce by remember{ mutableStateOf(true) }
if (imageUri.path?.isNotEmpty() == true && doOnce) {
println("choose "+imageUri)
navHostController.navigate("${HealthScreen.HealthCreateNutritionScreen.route}?$CNPHOTO=$imageUri ")
doOnce = false
}
}
CreateNutritionRoute 视图模型
我收到在要显示的屏幕的视图模型中发送的图像 URL。
init {
val capturedImage = savedStateHandle.get<String>(CNPHOTO)
println("viewmodel->"+capturedImage)
if(capturedImage != null && capturedImage.isNotEmpty())
_state.update {
it.copy(
image = capturedImage
)
}
}
这是我的导航图
composable(
route = "${HealthScreen.HealthCreateNutritionScreen.route}?$CNPHOTO={$CNPHOTO}",
arguments = listOf(
navArgument(name = CNPHOTO) {
type = NavType.StringType
defaultValue = ""
})
) {
CreateNutritionRoute(navHostController = navHostController)
}
这发生了
choose content://com.android.providers.media.documents/document/image%3A54
viewmodel->content://com.android.providers.media.documents/document/image:54
如您所见,它们彼此不同。所以图像没有显示。当我从图库中选择图像时,我在屏幕上看不到图像。我无法解决的问题是什么?
答:
0赞
Ratko Kostov
9/20/2023
#1
正如我所看到的,您面临的问题是 viewModel 中的 uri 是编码的,.当您将“imageUri”直接放入导航路线时,它会进行 URL 编码。
因此,请在使用前尝试对其进行解码。":" -> "%3A"
val capturedImage = savedStateHandle.get<String>(CNPHOTO)?.let { URLDecoder.decode(it, "UTF-8") }
评论
0赞
NewPartizal
9/20/2023
我认为你是对的,但它不起作用。尽管如此,两者还是不同的。两者都应该像这样“content://com.android.providers.media.documents/document/image%3A51”。我手动添加了像这样的视图模型中的状态更改 it.copy( image = “content://com.android.providers.media.documents/document/image%3A51” ) 并且它有效,但我认为这不是正确的方法
0赞
Ratko Kostov
9/20/2023
尝试在路由中添加编码,我认为这将解决您的问题。navHostController.navigate(“${HealthScreen.HealthCreateNutritionScreen.route}?$CNPHOTO=${Uri.encode(imageUri.toString())}”)。请记住,在 viewModel 中,如果要保持编码状态,则不应对其进行解码。
评论