为什么当我在 jetpack compose 中将参数作为参数传递到另一个屏幕时,我的 imageUri 会发生变化?

Why my imageUri change when I pass as a argument to another screen in jetpack compose?

提问人:NewPartizal 提问时间:9/20/2023 更新时间:9/20/2023 访问量:31

问:

我有一个屏幕用于从图库中选择照片,在此屏幕上,我从图库中选择照片,并将我选择的 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

如您所见,它们彼此不同。所以图像没有显示。当我从图库中选择图像时,我在屏幕上看不到图像。我无法解决的问题是什么?

Kotlin android-jetpack-compose 图像库 android-navigation android-gallery

评论


答:

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 中,如果要保持编码状态,则不应对其进行解码。