如何在 Compose 中预加载线圈图像?

Col*_*gon 12 android kotlin android-jetpack-compose coil

我有一个寻呼机(伴奏者),其图像是使用 Compose 中的 Coil 从网络获取的。

似乎仅在首次显示可组合项rememberPainter()时调用请求。Image

因此,当我在寻呼机中滑动页面时,Image仅在那一刻显示,因此我们必须等待一会儿。

有什么方法可以强制rememberPainter(线圈)预加载吗?


编辑1:

这是我的实现的一个简单版本(删除了很​​多内容,但这对结果没有影响):

@Composable
private fun Foo(imageList: List<ImageHolder>) {
    if (imageList.isEmpty())
        return

    val painterList = imageList.map {
        rememberImagePainter(
            data = it.getDataForPainter(),
            builder = {
                crossfade(true)
            })
    }

    ImageLayout(imageList, painterList)
}

@Composable
fun ImageLayout(imageList: List<ImageHolder>, painterList: List<Painter>) {
    HorizontalPager(
        count = imageList.size,
        modifier = Modifier.fillMaxWidth(),
    ) { page ->
        Image(
            painter = painterList[page],
            "",
            modifier = Modifier
                .fillMaxWidth()
                .height(200.dp)
                .background(
                    imageList[page].colorAverage
                ),
            contentScale = ContentScale.Crop
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

我也尝试直接在图像上使用 RememberImagePainter,以防万一。但问题很明显,第 2、3、4 页的 Image() 未渲染,因此 Image 不会调用画家。我试图看看它内部是如何工作的,但找不到。


编辑2:我找到了一个解决方法,但它不干净

for (painter in painterList) 
    Image(painter = painter, contentDescription = "", modifier = Modifier.size(0.001.dp))
Run Code Online (Sandbox Code Playgroud)

它强制线圈加载图像,并且尺寸非常小0.001.dp0不加载)。另外问题是,在构建器中,您需要强制一个尺寸,否则它只会加载一个像素,因此我强制图像的完整尺寸,因为我不知道图像可用的尺寸是多少。

Phi*_*hov 16

在线圈文档中有一个关于预加载的部分。根据您的架构,您可以在不同的地方执行此操作,最简单的是使用LaunchedEffect

val context = LocalContext.current

LaunchedEffect(Unit) {
    val request = ImageRequest.Builder(context)
        .data("https://www.example.com/image.jpg")
        // Optional, but setting a ViewSizeResolver will conserve memory by limiting the size the image should be preloaded into memory at.

        // For example you can set static size, or size resolved with Modifier.onSizeChanged
        // .size(coil.size.PixelSize(width = 100, height = 100))

        // or resolve display size if your images are full screen
        // .size(DisplaySizeResolver(context))

        .build()
    context.imageLoader.enqueue(request)
}
Run Code Online (Sandbox Code Playgroud)

在2.0.0版本之前使用LocalImageLoader.current而不是context.imageLoader获取图像加载器。