androidkotlinandroid-jetpack-composegifcoil

Load GIF from URL in Jetpack Compose using Coil


I want to show GIFs from URLs in my Jetpack Compose app. From what I can see, Coil is the only way to do it currently. It seems that the ImageRequest.Builder(context).data() method accepts the httpUrl data type, however, I have not gotten it to work. Is it even possible? If not, is there any other way to do it? I am new to Compose so this might have a simple solution.

I used this answer https://stackoverflow.com/questions/71138477/is-it-possible-to-display-animated-gif-in-jetpack for the image builder. I am not getting any errors but the grid is not showing up. I also tried a very simple implementation of AsyncImage() but that did not work either.

Here is my code:

@Composable
fun GifGrid(
    modifier: Modifier = Modifier,
    gifList: List<GiphyItem>
) {
    val context = LocalContext.current
    val imageLoader = ImageLoader.Builder(context)
        .components {
            if (SDK_INT >= 28) {
                add(ImageDecoderDecoder.Factory())
            } else {
                add(GifDecoder.Factory())
            }
        }
        .build()

    LazyVerticalStaggeredGrid(
        columns = StaggeredGridCells.Fixed(3),
        modifier = modifier,
        verticalItemSpacing = 12.dp,
        horizontalArrangement = Arrangement.spacedBy(12.dp),
        contentPadding = PaddingValues(vertical = 8.dp),
        content = {
            items(gifList) { item ->
                Image(
                    painter = rememberAsyncImagePainter(
                        ImageRequest.Builder(context).data(item.url.toHttpUrl()).apply(block = {
                            size(Size.ORIGINAL)
                        }).build(), imageLoader = imageLoader
                    ),
                    contentDescription = null,
                    modifier = Modifier.clip(
                        RoundedCornerShape(6.dp),
                    )
                )
            }
        }
    )
}

GiphyItem data class:

data class GiphyItem(
    val id: String = "",
    val url: String = ""
)

Solution

  • For anyone who might be lost, my issue was not at all with the composable itself. It was the url from Giphy I was using,- AsyncImage only renders GIFs whose urls end with .gif. Rookie mistake. :D I needed to dig deeper into the GIF Object of the Giphy API. Also, here is the composable grid I ended up using:

    @Composable
    fun GifGrid(
        modifier: Modifier = Modifier,
        gifList: List<GiphyItem>
    ) {
        LazyVerticalStaggeredGrid(
            columns = StaggeredGridCells.Fixed(3),
            modifier = modifier,
            verticalItemSpacing = 12.dp,
            horizontalArrangement = Arrangement.spacedBy(12.dp),
            contentPadding = PaddingValues(vertical = 8.dp),
            content = {
                items(gifList, key = { it.id }) { item ->
                    AsyncImage(
                        model = ImageRequest.Builder(LocalContext.current)
                            .data(item.images.downsized.url)
                            .decoderFactory(ImageDecoderDecoder.Factory())
                            .build(),
                        contentDescription = null,
                        modifier = Modifier
                            .clip(RoundedCornerShape(6.dp)),
                        contentScale = ContentScale.Crop
                    )
                }
            }
        )
    }