资讯动态

Glide 动图循环控制:播放次数、结束回调与资源清理怎么做

发布时间:2026/10/27 18:45:04 来源:尧图企业网站定制
Glide 动图循环控制播放次数、结束回调与资源清理怎么做【免费下载链接】glideAn image loading and caching library for Android focused on smooth scrolling项目地址: https://gitcode.com/gh_mirrors/gl/glideGlide 加载 GIF/WebP 动图时默认行为是无限循环而setLoopCount加动画结束回调是打破这个默认的关键。掌握它们之后你能判断一个动图需求该在哪个环节介入也能快速定位播放次数不生效结束后没停这类问题的根源。什么需求下你需要控制播放次数三个典型场景先对号入座引导类动效首页新功能引导动画用户首次进入播放 2 次后停在最后一帧不干扰操作触发条件是首次加载需要控制的是一次性播放次数。状态提示动画搜索结果页的加载占位动图正常时循环播放切走页面必须停止否则后台还在解码帧这里要控制的是生命周期内的启停。任务完成动画上传成功后播放一次庆祝动画播完弹出查看结果按钮需要控制的不仅是次数还有播完这一刻的回调时机。共同点只要动画结束要触发别的 UI 动作就不能只靠无限循环必须拿到播放结束这个事件。理解三个角色GifDrawable、帧加载器与循环计数用一句话说清分工方便你复述给别人听GifDrawable是 Glide 给动图返回的 Drawable 对象你从into的资源回调里拿到它。它持有maxLoopCount字段默认值是LOOP_FOREVER-1表示无限循环LOOP_INTRINSIC0表示沿用动图文件里自带的循环次数GIF 场景下就是 netscape 扩展块里的数值。GifFrameLoader帧加载器负责按帧解码和推进。每次start()时 GifDrawable 会向它订阅每解出一帧就回调onFrameReady()。循环计数在onFrameReady()里推进当帧索引走到最后一帧时loopCount一旦loopCount maxLoopCount且上限不是 -1就自动stop()并通知所有已注册的AnimationCallback。由此可以推出两条重要性质回调只在因达到次数上限而停止时触发手动stop()不会触发start()会重置loopCount为 0所以重启播放就是再调一次start()。最短验证路径三步跑通结论先说在资源就绪的回调里设置次数注册结束后要执行的逻辑页面销毁时停掉并清理。不要试图在into之前设置那时 Drawable 还不存在。第一步拿到资源后设置次数。用asGif()或带RequestListener的into都行// onResourceReady 回调内 if (resource instanceof GifDrawable) { gifDrawable (GifDrawable) resource; gifDrawable.setLoopCount(2); // 只播 2 轮 }第二步注册结束回调。registerAnimationCallback来自Animatable2Compat.AnimationCallbackgifDrawable.registerAnimationCallback(drawable - { // 仅当达到 setLoopCount 上限自动停止时触发 showRetryButton(); }); gifDrawable.start();第三步在生命周期出口清理。调用链是onDestroy - stop() - clearAnimationCallbacks()防止回调持有页面引用导致泄漏Override protected void onDestroy() { super.onDestroy(); if (gifDrawable ! null) { gifDrawable.stop(); gifDrawable.clearAnimationCallbacks(); } }如果你走的是Target方式SimpleTarget/CustomTarget清理动作应放在onLoadCleared里而不是只依赖 Activity 生命周期。仓库的 samples/giphy 示例展示了用RequestListener捕获 GifDrawable 的完整写法可直接对照阅读。三类故障信号与对应处理动作信号一setLoopCount 调了动图仍无限循环。先查三个点是否调用了asGif()用asDrawable()或普通load().into()拿到的可能不是 GifDrawable是否在资源真正就绪后才调用是否误传了非法值setLoopCount接受正整数、LOOP_FOREVER或LOOP_INTRINSIC其他值会直接抛IllegalArgumentException。定位方法很简单在回调里打印resource.getClass()确认类型再谈后续。信号二页面已销毁动画回调仍在触发或内存持续增长。说明AnimationCallback持有 Activity 强引用且未注销。判断方法在onDestroy打断点确认执行了stop()和clearAnimationCallbacks()若回调写在匿名内部类里捕获了页面优先改成弱引用持有或把回调对象声明为成员变量以便精确unregisterAnimationCallback。信号三设了 3 次视觉上像播了 4 次或 2 次。两个常见原因一是在start()之后才设的次数没赶上第一轮计数start()会重置计数但设置时机与播放顺序要一致二是LOOP_INTRINSIC模式下文件自带循环数与预期不符。处理动作统一按设次数 → 注册回调 → start的固定顺序执行且重启播放前不要自行维护额外计数器以onAnimationEnd触发次数为准做验收。性能、兼容与边界尺寸动图内存与目标尺寸平方级相关RequestBuilder上先用override(width, height)或sizeMultiplier约束再谈次数控制顺序反了会白白多占内存。格式边界asGif()返回的始终是 GifDrawableWebP 动图能否走这条路取决于解码器注册与系统版本行为与 GIF 不完全一致跨机型要实测。可见性GifDrawable 在setVisible(false)时会自动停止解码、恢复可见后重启列表滚动天然受益但反过来手动stop()后不会因重新可见而自动恢复两者语义不同。单帧边界帧数为 1 时不进入解码循环onAnimationEnd不会触发别把这类资源当动图处理。ROM 差异低端机和部分定制 ROM 的解码速度不一结束回调的到达时间会波动UI 跳转不要依赖精确时长。关键方法触发时机结果setLoopCount(n)资源就绪后、start 前覆盖默认无限循环registerAnimationCallback任意生效于下一次达标停止达标停止时回调start()动画未运行时重置计数并开播stop()任意立即停不触发结束回调发布前检查清单确认在资源就绪回调中拿到GifDrawable实例后再调用setLoopCount确认加载入口用的是asGif()且资源确实是动图而非静态图确认setLoopCount传值为正整数、LOOP_FOREVER或LOOP_INTRINSIC之一确认结束回调按达标停止语义使用不依赖手动 stop 触发确认onDestroy/onLoadCleared中执行了stop与clearAnimationCallbacks确认回调不持有 Activity 强引用或已有弱引用/成员变量方案用override约束了目标尺寸并在低端机验证过播放与结束时机核心实现位于 GifDrawable.java帧推进逻辑在同目录的 GifFrameLoader.java整体项目说明见 README.md。【免费下载链接】glideAn image loading and caching library for Android focused on smooth scrolling项目地址: https://gitcode.com/gh_mirrors/gl/glide创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑