I adopted this solution here: https://github.com/jaredsburrows/android-gif-example/commit/5690523c6dc40c435c3d81868d89ba26d21e3663 since it was removed from Accompanist here.
Code:
class ImageService @Inject constructor(@ApplicationContext private val context: Context) {
/** Compose views */
fun loadGif(
imageUrl: String,
thumbnailUrl: String,
onResourceReady: (GifDrawable?) -> Unit,
onLoadFailed: () -> Unit,
) {
loadGif(imageUrl)
.override(SIZE_ORIGINAL, SIZE_ORIGINAL)
.thumbnail(loadGif(thumbnailUrl))
.into(object : CustomTarget<GifDrawable>() {
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
onLoadFailed.invoke()
}
override fun onLoadCleared(placeholder: Drawable?) {
onLoadFailed.invoke()
}
override fun onResourceReady(
resource: GifDrawable,
transition: Transition<in GifDrawable>?,
) {
onResourceReady.invoke(resource)
}
})
}
/** ImageViews */
fun loadGif(
imageUrl: String,
thumbnailUrl: String,
imageView: ImageView,
onResourceReady: () -> Unit,
onLoadFailed: (GlideException?) -> Unit,
) {
loadGif(imageUrl)
.override(SIZE_ORIGINAL, SIZE_ORIGINAL)
.thumbnail(loadGif(thumbnailUrl))
.listener(
object : RequestListener<GifDrawable> {
override fun onResourceReady(
resource: GifDrawable?,
model: Any?,
target: Target<GifDrawable>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
onResourceReady.invoke()
return false
}
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<GifDrawable>?,
isFirstResource: Boolean
): Boolean {
onLoadFailed.invoke(e)
return false
}
}
)
.into(imageView)
.clearOnDetach()
}
private fun loadGif(imageUrl: String): RequestBuilder<GifDrawable> {
return GlideApp.with(context)
.asGif()
.transition(withCrossFade())
.load(imageUrl)
}
}
See the code here: https://github.com/jaredsburrows/android-gif-example/blob/52914cd63b528b3a9365df6bfa2134ffdfa0e0d7/app/src/main/java/com/burrowsapps/example/gif/data/ImageService.kt#L22
Usage:
composeView.setContent {
val showProgressBar = remember { mutableStateOf(true) }
val state = remember { mutableStateOf<GifDrawable?>(null) }
GifTheme {
// Load images - 'tinyGifPreviewUrl' -> 'tinyGifUrl'
imageService.loadGif(
imageUrl = imageInfoModel.tinyGifUrl,
thumbnailUrl = imageInfoModel.tinyGifPreviewUrl,
onResourceReady = { resource ->
showProgressBar.value = false
state.value = resource
},
onLoadFailed = {
showProgressBar.value = false
state.value = null
},
)
// Show loading indicator when image is not loaded
if (showProgressBar.value) {
CircularProgressIndicator(
modifier = Modifier
.fillMaxWidth()
.height(128.dp)
.padding(all = 24.dp),
)
} else {
Image(
painter = rememberDrawablePainter(drawable = state.value),
contentDescription = stringResource(id = R.string.gif_image),
contentScale = ContentScale.Crop,
modifier = Modifier
.fillMaxWidth()
.height(135.dp),
)
}
}
}
See the code here: https://github.com/jaredsburrows/android-gif-example/blob/52914cd63b528b3a9365df6bfa2134ffdfa0e0d7/app/src/main/java/com/burrowsapps/example/gif/ui/giflist/GifAdapter.kt#L73