【问题标题】:How to correctly upload image to an item in LazyList in Jetpack Compose?如何正确地将图像上传到 Jetpack Compose 中的 LazyList 中的项目?
【发布时间】:2022-12-05 01:25:22
【问题描述】:

我想让用户将图像添加到 LazyColumn 中的每个项目(卡片)。但似乎图像在重组时被删除了。我该如何解决?

@Composable
fun PhotoUpload(
) {
    val imageUri = remember {
        mutableStateOf<Uri?>(null)
    }
    val context = LocalContext.current
    val bitmap = remember {
        mutableStateOf<Bitmap?>(null)
    }

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

    imageUri.value?.let {
        LaunchedEffect(Unit) {
            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)
        )
    }

    Button(onClick = {
        launcher.launch("image/*")
    }) {
        Icon(Icons.Filled.PhotoAlbum, "")
    }
}

图片被删除(他们不会回来,这是一个循环 gif)

PS:对于 LazyColumn,我确实使用键。我也尝试使用 Coil 的 AsyncImage,但它有同样的问题

【问题讨论】:

    标签: android kotlin android-jetpack-compose lazycolumn


    【解决方案1】:

    您可以将 Uris 或 Uris 作为 String 存储在数据类中,例如

    @Immutable
    data class MyModel(
        val title: String,
        val description: String,
        val uri: Uri? = null
    )
    

    并创建一个包含项目的 ViewModel 和一个在设置时更新 Uri 的函数

    class MyViewModel : ViewModel() {
        val items = mutableStateListOf<MyModel>()
            .apply {
                repeat(15) {
                    add(MyModel(title = "Title$it", description = "Description$it"))
                }
            }
    
        fun update(index: Int, uri: Uri) {
            val item = items[index].copy(uri = uri)
            items[index] = item
        }
    }
    

    并通过单击按钮获取 Uri

    @Composable
    fun PhotoUpload(
        onError: (() -> Unit)? = null,
        onImageSelected: (Uri) -> Unit
    ) {
    
        val launcher = rememberLauncherForActivityResult(
            contract = ActivityResultContracts.GetContent()
        ) { uri: Uri? ->
            if (uri == null) {
                onError?.invoke()
            } else {
                onImageSelected(uri)
            }
    
        }
    
        Button(onClick = {
            launcher.launch("image/*")
        }) {
            Icon(Icons.Filled.PhotoAlbum, "")
        }
    }
    

    设置后通过回调返回 Uri 的行

    @Composable
    private fun MyRow(
        title: String,
        description: String,
        uri: Uri?,
        onImageSelected: (Uri) -> Unit
    ) {
        Column(
            modifier = Modifier
                .shadow(ambientColor = Color.LightGray, elevation = 4.dp)
                .fillMaxWidth()
                .background(Color.White, RoundedCornerShape(8.dp))
                .padding(8.dp)
        ) {
            Text(title)
            Text(description)
            uri?.let { imageUri ->
                AsyncImage(
                    modifier = Modifier
                        .fillMaxWidth()
                        .aspectRatio(4 / 3f),
                    model = imageUri, contentDescription = null
                )
            }
            PhotoUpload(onImageSelected = onImageSelected)
        }
    }
    

    用法

    @Composable
    private fun ImageUploadSample(viewModel: MyViewModel) {
        LazyColumn {
    
            itemsIndexed(
                key = { _, item ->
                    item.hashCode()
                },
                items = viewModel.items
            ) { index, myModel ->
                MyRow(
                    title = myModel.title,
                    description = myModel.description,
                    uri = myModel.uri,
                    onImageSelected = { uri ->
                        viewModel.update(index, uri)
                    }
                )
            }
        }
    }
    

    结果

    【讨论】:

      猜你喜欢
      • 2021-08-28
      • 2022-07-04
      • 1970-01-01
      • 1970-01-01
      • 2023-02-11
      • 2022-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多