glide
glide copied to clipboard
[Glide Compose] How to play/pause a GIF ?
Glide Version: 5.0.0-rc1 Glide Compose Version: 1.0.0-beta01
Device/Android Version: Not relevant
Issue details / Repro steps / Use case background:
I am using the GlideImage composable to display gifs in a LazyColumn. I'm looking for a way to pause/play (ideally from the beginning) the GIF.
Using an AndroidView with an ImageView, I can call resource.stop() and resource.startFromFirstFrame() and its works.
With compose I can't see how to reproduce this use case.
What I've tried for the moment, which simulates this behaviour
if (!gifState.isPlaying) {
GlideImage(
model = model, contentDescription = null, modifier = Modifier
.height(150.dp)
.widthIn(min = 200.dp),
) {
it.dontAnimate()
}
} else {
GlideImage(
model = model, contentDescription = null, modifier = Modifier
.height(150.dp)
.widthIn(min = 200.dp),
)
}
There are 2 problems with this approach:
-
When I click on my cell to change the
isPlayingboolean, there is a flicker on the first load between the animated gif and the static image. -
I'd like to play the GIF from the beginning but it resumes where it left off
Subsidiary question: is it possible not to share the same GifFrameLoader when displaying the same GIF in several different cells?
Because of this, the cells all display the same gif frame, even if the gif is played at different times.
What I also tried was to use AndroidView:
AndroidView(
factory = { context ->
val view = ImageView(context).apply {
layoutParams = ViewGroup.LayoutParams(WRAP_CONTENT, MATCH_PARENT)
adjustViewBounds = true
}
Glide.with(view).asGif().load(model).addListener(object : RequestListener<GifDrawable> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<GifDrawable>, isFirstResource: Boolean): Boolean {
return false
}
override fun onResourceReady(resource: GifDrawable, model: Any, target: Target<GifDrawable>?, dataSource: DataSource, isFirstResource: Boolean): Boolean {
if (gifState.isPlaying) {
resource.stop()
resource.startFromFirstFrame()
} else {
resource.stop()
}
view.setImageDrawable(resource)
return true
}
}).into(view)
view
},
update = { view ->
(view.drawable as? GifDrawable)?.let { gifDrawable ->
if (gifState.isPlaying) {
gifDrawable.stop()
gifDrawable.startFromFirstFrame()
} else {
gifDrawable.stop()
}
}
})
This code works correctly for stopping/resuming a GIF from the beginning, but when it is used in several cells, the display becomes very strange and the application ends up crashing with the "Can't restart a running animation" message from the GifFrameLoader.