Search code examples
androidkotlinimage-cachingcoil

Android Coil loads removes old image to early when loading new image


So I have image that is shown and over that image I load another image like this:

 AsyncImage(
            modifier = modifier,
            model = modelBuilder(
                ImageRequest.Builder(LocalContext.current)
                    .data(image.url)
                    .loadWitchCache(image.url)
                    .let {
                        if (placeholder != null) {
                            it.fallback(placeholder).error(placeholder)
                        } else {
                            it
                        }
                    },
                image.url,
            ).build(),
            contentDescription = contentDescription,
            alignment = alignment,
            contentScale = contentScale,
        )




fun ImageRequest.Builder.loadWitchCache(url: String): ImageRequest.Builder {
return this.diskCachePolicy(CachePolicy.ENABLED)
    .diskCacheKey(url)
    .memoryCachePolicy(CachePolicy.ENABLED)
    .memoryCacheKey(url)

}

The problem is that in app I have list of images that user can pick. When he picks image, it is drawn. Problem is that when I choose new image, there is transition where I don't see old or new image. I see Image that is placeholder under that. What is interesting is that when user picks second or third time the same image, than there is no this transition delay and all we can see is old image and imediatly new one when loaded.

This takes us to conclusion that when image is cached, it takes it from cache and there is not this delay. But why can't we tell Coil to do it anyways and remove old image only when new is loaded...

I tried lot of things, but nothing helped. It has to be some way. Anyone knows to solve it? Thanks in advance...


Solution

  • Here is solution guys. CommonsWare got the right idea:

     var oldImage: Drawable? by remember {
        mutableStateOf(null)
    }
    when (image) {
        is ImageResource.ByUrl -> {
            AsyncImage(
                modifier = modifier,
                model = modelBuilder(
                    ImageRequest.Builder(LocalContext.current)
                        .data(image.url)
                        .placeholder(oldImage)
                        .loadWitchCache(image.url)
                        .listener(onSuccess = { _, successResult ->
                            oldImage = successResult.drawable
                        })
                        .let {
                            if (placeholder != null) {
                                it.fallback(placeholder).error(placeholder)
                            } else {
                                it
                            }
                        },
                    image.url,
                ).build(),
                contentDescription = contentDescription,
                alignment = alignment,
                contentScale = contentScale,
            )
        }