【问题标题】:How to preload Coil image in Compose?强制 Coil Compose 直接加载记住图像
【发布时间】:2021-10-16 17:29:55
【问题描述】:

我有一个寻呼机(伴奏),其图像是通过 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
        )
    }
}

为了以防万一,我也尝试直接在 Image 上使用 rememberImagePainter。 但问题显然是第 2、3、4 页的 Image() 未呈现,因此 Image 不会调用画家。我试图看看它是如何工作的,但找不到。


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

for (painter in painterList) 
    Image(painter = painter, contentDescription = "", modifier = Modifier.size(0.001.dp))

它强制线圈加载图像并且尺寸非常小,如0.001.dp0 不加载)。 还有一个问题是,在构建器中你需要强制一个大小,否则它只会加载一个像素,所以我强制图像的全尺寸,因为我不知道图像可以使用什么尺寸。

【问题讨论】:

  • 根据我的经验,线圈会很好地缓存图像,即使在应用程序销毁和重新创建之后,缓存的图像仍然存在,我什至不需要连接到互联网就可以拥有它渲染。
  • 只需发布您的实现,最好是某些级别的父容器,以便我们可以挖掘问题。
  • @MARSK 我添加了我的代码示例来重现问题。但问题显然是其他页面的 Image() 没有显示,所以没有提出线圈画家的请求
  • @MARSK 问题也不在于缓存,我加载的图像可能会发生很大变化,并且会在这里随机显示。从我看到的缓存工作完美。

标签: android kotlin android-jetpack-compose coil


【解决方案1】:

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

val context = LocalContext.current
val imageLoader = LocalImageLoader.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()
    imageLoader.enqueue(request)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 2022-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-06
    • 1970-01-01
    • 2015-09-26
    相关资源
    最近更新 更多