使用 Coil 和 Jetpack Compose 有条件地显示图库或可绘制资源中的图像

Conditionally show image from the gallery or drawable resource using Coil and Jetpack Compose

我正在尝试将图库中的图像显示为用户选择的任何内容,或者将可绘制资源中图像文件中的图像显示为默认图像,但无法正常工作。我正在使用 Coil 编写并已经添加了依赖项。这是代码:

class MainActivity : ComponentActivity() {
    private var imageUriState = mutableStateOf<Uri?>(null)

    private val selectImageLauncher = registerForActivityResult(GetContent()) { uri ->
        imageUriState.value = uri
    }

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

    @Composable
    fun ImageSourceActivityScreen() {
        Column(
            modifier = Modifier.fillMaxSize(),
            verticalArrangement = Arrangement.Center
        ) {
            Image(
                painter = rememberImagePainter(
                    if (imageUriState != null) {
                        imageUriState.value
                    } else {
                        R.drawable.blank_profile_picture
                    }
                ),
                contentDescription = "profile image",
                contentScale = ContentScale.Crop,
                modifier = Modifier.fillMaxWidth()
            )
    ...
}

没有显示错误,但也没有显示默认图像。请帮助使其工作。谢谢!

您可以使用builder参数设置一个placeholder:

val painter = rememberImagePainter(
    imageUriState.value,
    builder = {
        placeholder(R.drawable.blank_profile_picture)
    }
)
Image(
    painter,
    contentDescription = "profile image",
    contentScale = ContentScale.Crop,
    modifier = Modifier.fillMaxWidth()
)

您的代码无效,因为您将 imageUriStatenull 进行比较,后者始终为真

您有两个选择:

  1. 根据您的状态值指定画家
Image(
    painter = if (imageUriState.value != null) {
        rememberImagePainter(
            imageUriState.value
        )
    } else {
        painterResource(id = R.drawable.blank_profile_picture)
    },
    contentDescription = "profile image",
    contentScale = ContentScale.Crop,
    modifier = Modifier.fillMaxWidth()
)
  1. 默认情况下,如果您将 null 作为数据传递,coil 不会向您显示占位符,这通常是有道理的。如果你想在没有图像时和等待图像加载时都看到你的占位符,你可以创建这样的函数:
@Composable
inline fun rememberImagePainter(
    data: Any?,
    @DrawableRes emptyPlaceholder: Int,
    builder: ImageRequest.Builder.() -> Unit = {},
): Painter {
    val painter = rememberImagePainter(
        data,
        builder = {
            placeholder(emptyPlaceholder)
            builder()
        }
    )
    if (data == null) {
        return painterResource(emptyPlaceholder)
    }
    return painter
}

// usage
Image(
    painter = rememberImagePainter(
        "https://i.stack.imgur.com/rkyep.jpg",
        emptyPlaceholder = R.drawable.test,
    ),
    contentDescription = "profile image",
    contentScale = ContentScale.Crop,
    modifier = Modifier.fillMaxSize()
)

从@Gabriele Mariotti 的回答中找到了在哪里查找错误的提示。我在没有 .value 的情况下调用 imageUriState。修复了它,它现在正在工作。谢谢大家的帮助!

Image(
    painter = rememberImagePainter(
        if (imageUriState.value != null) {
            imageUriState.value
        } else {
            R.drawable.blank_profile_picture
        }
    ),
    contentDescription = "profile image",
    contentScale = ContentScale.Crop,
    modifier = Modifier.fillMaxWidth()
)