Android中使用Fresco 2.6.0实现GIF仅播放一次后显示占位图
解决Fresco中GIF仅播放一次后切换到占位图的问题
要实现GIF只播放一次、之后显示占位图或原图的需求,核心是监听动画的结束事件,在动画播放完成后停止动画并切换显示内容。你可以通过给Animatable添加AnimationListener来实现,具体修改如下:
修改后的代码
val gifController: DraweeController = Fresco.newDraweeControllerBuilder() .setUri(UriUtil.getUriForResourceId(R.drawable.save_draft)) .setControllerListener(object : BaseControllerListener<ImageInfo?>() { private var animationListener: Animation.AnimationListener? = null override fun onFinalImageSet( id: String, imageInfo: ImageInfo?, anim: Animatable? ) { anim?.let { // 监听动画结束事件 animationListener = object : Animation.AnimationListener { override fun onAnimationStart(animation: Animation?) {} override fun onAnimationRepeat(animation: Animation?) {} override fun onAnimationEnd(animation: Animation?) { // 动画结束后停止播放 it.stop() // 切换到占位图/原图,替换为你需要的资源ID iv.controller = Fresco.newDraweeControllerBuilder() .setUri(UriUtil.getUriForResourceId(R.drawable.your_placeholder)) .build() // 移除监听器避免内存泄漏 it.removeAnimationListener(this) } } it.addAnimationListener(animationListener) it.start() } } override fun onRelease(id: String) { // 控制器释放时清理监听器 animationListener?.let { listener -> (iv.controller?.animatable as? Animatable)?.removeAnimationListener(listener) } } }) .build() iv.controller = gifController
关键说明
- 监听动画结束:通过
Animation.AnimationListener的onAnimationEnd回调,精准捕获动画播放完成的时机,执行后续操作。 - 切换显示内容:动画结束后重新构建控制器,加载你需要的占位图或原图资源,覆盖原GIF的显示。
- 内存泄漏防护:在控制器释放的
onRelease回调中移除动画监听器,避免不必要的引用持有。
如果需要显示GIF的第一帧而非额外占位图,可以提前将GIF的第一帧导出为静态图片资源,再在动画结束时加载该资源即可。
内容的提问来源于stack exchange,提问作者Vanisha Gaba
相关产品推荐
相关产品推荐

