使用 Coil Compose 加载本地可绘制对象

Loading local drawables with Coil Compose

我最近migrated from Accompanist's ImagePainter to Coil's,下面是我更新后的相关代码。

val painter = rememberImagePainter(DRAWABLE_RESOURCE_ID)

when (painter.state) {
    is ImagePainter.State.Empty -> Timber.w("Empty")
    is ImagePainter.State.Loading -> {
        Box(
            contentAlignment = Alignment.Center,
            modifier = Modifier.wrapContentSize()
        ) {
            CircularProgressIndicator()
        }
    }
    is ImagePainter.State.Success -> {
        Image(
            painter = painter,
            contentDescription = null,
            contentScale = ContentScale.Fit,
            modifier = Modifier
                .padding(8.dp)
                .size(84.dp)
                .clip(RoundedCornerShape(corner = CornerSize(16.dp)))
        )
    }
    is ImagePainter.State.Error -> Timber.e("Error")
}

现在这些图像不会呈现,painter.state 始终是 Empty。我的遗留伴奏器实现在代码中此时显示图像。如果我使用来自 Compose 的股票 painterResource(resId),它也有效。

我错过了什么来执行 Coil 的新 painter 通过其状态?

您不需要线圈来加载本地资源。您可以使用系统 painterResource:

Image(
    painter = painterResource(id = R.drawable.test),
    contentDescription = null,
    contentScale = ContentScale.Fit,
    modifier = Modifier
        .padding(8.dp)
        .size(84.dp)
        .clip(RoundedCornerShape(corner = CornerSize(16.dp)))
)

如果您要使用它来移除图像加载:由于从伴奏者移动到 coil,画家将不会开始加载,除非 Image 在视图树层次结构中。因此,您可以使用 while:

Image 移动到 Box
Box(contentAlignment = Alignment.Center) {
    val painter = rememberImagePainter(R.drawable.test)
    Image(
        painter = painter,
        contentDescription = null,
        contentScale = ContentScale.Fit,
        modifier = Modifier
            .padding(8.dp)
            .size(84.dp)
            .clip(RoundedCornerShape(corner = CornerSize(16.dp)))
    )
    when (painter.state) {
        is ImagePainter.State.Empty -> Timber.w("Empty")
        is ImagePainter.State.Loading -> {
            Box(
                contentAlignment = Alignment.Center,
                modifier = Modifier.wrapContentSize()
            ) {
                CircularProgressIndicator()
            }
        }
        is ImagePainter.State.Success -> {

        }
        is ImagePainter.State.Error -> Timber.e("Error")
    }
}

此外,当您没有提供足够的大小修饰符时,它可能不会开始加载(这不是您的情况,只是为了让您知道)。查看 了解更多信息。

根据的建议,您不需要线圈来加载本地资源。

如果你想使用它,你可以简单地使用你的代码:

val painter = rememberImagePainter(R.drawable.xxx)
val state = painter.state
Box(
    contentAlignment = Alignment.Center,
    modifier = Modifier.wrapContentSize()
) {
    AnimatedVisibility(visible = (state is ImagePainter.State.Loading)) {
        CircularProgressIndicator()
    }
    Image(
        painter = painter,
        contentDescription = null,
        modifier = Modifier.size(128.dp)
    )
}

val context = LocalContext.current
val imageLoader = ImageLoader(context)

val request = ImageRequest.Builder(context)
        .data(thumbnailUrl)
        .build()

val painter = rememberImagePainter(
        request = request,
        imageLoader = imageLoader
    )

val state = painter.state

Image(
  painter = painter,
  contentDescription = "thumbnail image",
  modifier = Modifier
            .fillMaxSize()
            .placeholder(
                visible = state is ImagePainter.State.Loading,
                color = PlaceholderDefaults.color(
                    backgroundColor = SMXTheme.colors.shimmer.copy(0.1f),
                ),
                highlight = PlaceholderHighlight.shimmer(),
            ),
        contentScale = ContentScale.Crop
    )