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 = ""
)
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
)
}
}
)
}