1

我最近从 Accompanist's 迁移ImagePainter到 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。我的旧版 Accompanist 实现在代码中此时显示了图像。如果我使用painterResource(resId)Compose 的库存,它也可以工作。

painter通过其状态执行 Coil 的 new 我缺少什么?

4

3 回答 3

1

您不需要使用线圈来加载本地资源。您可以使用系统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)))
)

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

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")
    }
}

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

于 2021-08-26T04:24:27.503 回答
1

正如@Philip Dukhov所建议的,您不需要使用线圈来加载本地资源。

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

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)
    )
}

在此处输入图像描述

于 2021-08-26T07:26:22.853 回答
0
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
    )
于 2022-02-16T03:31:43.197 回答