首页 > 解决方案 > Jetpack compose 库中的图像选择器 - Android/Kotlin

问题描述

我想使用 Jetpack compose 实现一个图像选择器我正在寻找解决方案,我发现了一些像这样的教程https://ngengesenior.medium.com/pick-image-from-gallery-in-jetpack-compose-5fa0d0a8ddaf我用过他们解释的代码,它运行良好,但我有一个问题!

我的应用程序包含一个活动“MainActivity”,它开始呈现组合组件,我的一个屏幕是一个表单,其中包含一个用于选择图像的字段和其他字段,当我使用下面的代码时,它会打开图库并选择一个图像,然后单击好的,它转到 MainActivity,但我需要留在表单的同一屏幕上,以便用户可以继续填写表单,我将列出代码,希望有人可以帮助我

val launcher = rememberLauncherForActivityResult(contract =
    ActivityResultContracts.GetContent()) { uri: Uri? ->
        imageUri = uri
    }
    Column() {
        Button(onClick = {
            launcher.launch("image/*")
        }) {
            Text(text = "Pick image")
        }

        Spacer(modifier = Modifier.height(12.dp))

        imageUri?.let {
            if (Build.VERSION.SDK_INT < 28) {
                bitmap.value = MediaStore.Images
                    .Media.getBitmap(context.contentResolver,it)

            } else {
                val source = ImageDecoder
                    .createSource(context.contentResolver,it)
                bitmap.value = ImageDecoder.decodeBitmap(source)
            }

            bitmap.value?.let {  btm ->
                Image(bitmap = btm.asImageBitmap(),
                    contentDescription =null,
                    modifier = Modifier.size(400.dp))
            }
        }

    }
class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            Button(
                onClick = {
                    navController.navigate(AppScreens.FormScreen.route)
                },
                ) {
                Text(text = "Go to form screen" )
            }
        }
    }
}
@Composable
fun FormScreen() {
    var imageUri by remember { mutableStateOf<Uri?>(null) }
    val context = LocalContext.current
    var bitmap by remember { mutableStateOf<Bitmap?>(null) }

    val launcher = rememberLauncherForActivityResult(contract =
    ActivityResultContracts.GetContent()) { uri: Uri? ->
        imageUri = uri
    }

    Column {
        // some text field in the form
        // another number field in the form
        // select image filed in the form
        CustomInputFieldContainer(
            label = "select image"
        ) {
            Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) {
                Column(horizontalAlignment = Alignment.CenterHorizontally) {

                    imageUri?.let {
                        if (Build.VERSION.SDK_INT < 28) {
                            bitmap = MediaStore.Images
                                .Media.getBitmap(context.contentResolver,it)

                        } else {
                            val source = ImageDecoder
                                .createSource(context.contentResolver,it)
                            bitmap = ImageDecoder.decodeBitmap(source)
                        }

                        bitmap.let {  btm ->
                            Image(bitmap = btm.asImageBitmap(),
                                contentDescription =null,
                                modifier = Modifier.size(400.dp))
                        }

                    }

                    Button(
                        onClick = { launcher.launch("image/*") },
                        contentPadding = PaddingValues(),
                        modifier = Modifier.background(Color.Yellow)
                    ) {
                        Row(
                            modifier = Modifier
                                .fillMaxWidth()
                                .wrapContentSize(Alignment.BottomCenter)
                                .padding(vertical = 10.dp),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            Icon(imageVector = Icons.Filled.AddAPhoto, contentDescription = null)
                            Spacer(modifier = Modifier.width(8.dp))
                            Text(text = "Add Photo")
                        }
                    }
                }
            }
        }
    }


}

现在我想在单击选择图像按钮时从图库中选择一个图像,然后返回我的表单以完成其余字段,当我尝试上面的代码时,我可以选择一个图像,但它进入了主要活动,这让我丢失数据

对解决这个问题有什么帮助吗?

标签: androidkotlinandroid-jetpack-compose

解决方案


当您说“它工作正常”时,您的意思是您检查了“val imageUri'”是否选择了正确的文件 Uri?

从 Image-Picker 选择图像后,您是否从 logcat 收到任何错误?

试试这个,让我们知道它是否有任何作用

var imageUri = remember { mutableStateOf<Uri?>(null) } // UPDATE
val context = LocalContext.current
var bitmap by remember { mutableStateOf<Bitmap?>(null) }

val launcher = rememberLauncherForActivityResult(contract =
ActivityResultContracts.GetContent()) { uri: Uri? -> 
    imageUri.value = uri // UPDATE
}

推荐阅读