如何在Jetpack Compose中使用Coil显示自定义组合占位符?

3

我需要使用Coil在Jetpack Compose中展示一个自定义的占位符,但该占位符不是drawable,而是一个我自定义的组合函数。是否可以使用Coil实现这一点? 以下是我使用Coil的代码片段:

Image(
    modifier = Modifier
        .size(120.dp)
        .align(Alignment.CenterHorizontally),
    painter = rememberImagePainter(
        data = entry.imageUrl,
        builder = {
            crossfade(true)
            MyPlaceholder(resourceId = R.drawable.ic_video)
        },
    ),
    contentDescription = entry.pokemonName
)

这是我的自定义占位符组合函数:
@Composable
fun MyPlaceholder(@DrawableRes resourceId: Int) {
    Surface(
        modifier = Modifier.fillMaxSize(),
        color = Color(0xFFE0E0E0)
    ) {
        Box(
            modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center,
        ) {
            Surface(
                modifier = Modifier.size(30.dp),
                shape = CircleShape,
                color = Color.White
            ) {
                Image(
                    modifier = Modifier
                        .padding(
                            PaddingValues(
                                start = 11.25.dp,
                                top = 9.25.dp,
                                end = 9.25.dp,
                                bottom = 9.25.dp
                            )
                        )
                        .fillMaxSize(),
                    painter = painterResource(id = resourceId),
                    contentDescription = null
                )
            }
        }
    }
}

我的Gradle(Coil):

// Coil
implementation 'io.coil-kt:coil-compose:1.4.0'
2个回答

7

Coil 没有内置对可组合占位符的支持。

你可以将你的可组合放在 Box 内,并根据状态在 Image 上显示占位符。

在我的例子中,如果状态是 LoadingError,我会显示它。你可以为 Error 情况添加另一个视图参数,并使用 Crossfade 而不是 AnimatedVisibility

此外,我添加了 Modifier.matchParentSize()Image 以跟随在修饰器参数上计算的父容器大小。你不能直接将修饰器参数传递给 Image,因为像 align 这样的修饰器只适用于直接子元素,这就是为什么你总是要将其传递给容器视图。

@Composable
fun Image(
    painter: ImagePainter,
    placeholder: @Composable () -> Unit,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null,
) {
    Box(modifier) {
        Image(
            painter = painter,
            contentDescription = contentDescription,
            alignment = alignment,
            contentScale = contentScale,
            alpha = alpha,
            colorFilter = colorFilter,
            modifier = Modifier.matchParentSize()
        )

        AnimatedVisibility(
            visible = when (painter.state) {
                is ImagePainter.State.Empty,
                is ImagePainter.State.Success,
                -> false
                is ImagePainter.State.Loading,
                is ImagePainter.State.Error,
                -> true
            }
        ) {
            placeholder()
        }
    }
}

使用方法:

Image(
    painter = rememberImagePainter(imageUrl),
    placeholder = {
        CustomComposableView(...)
    },
    contentDescription = "...",
    modifier = Modifier
        ...
)

2

自从 Coil 2.0 后,就有了一个 SubcomposeAsyncImage 来解决您的问题。以下是如何使用它的示例:

SubcomposeAsyncImage(
    model = "https://example.com/image.jpg",
    loading = {
        CircularProgressIndicator()
    },
    ...
)

欲了解更多信息,请参阅官方文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接