我们在开发中经常会做一些 Gif 展示,而一些开源的图片框架如 Glide、Fresco、GifImageView 也能够展示 Gif,GifImageView 可以直接设置播放次数,而 Fresco 好像并没有设置播放次数的,就需要我们自己来处理。
首先,要使用 Fresco 就得先依赖,注意两个版本得一致:
implementation 'com.facebook.fresco:fresco:1.5.0'
implementation 'com.facebook.fresco:animated-gif:1.5.0'
那我们一般来说使用 Fresco 展示 Gif 是怎么操作呢?
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(uri)
// 这个是设置自动播放动画,在源码中就是当图片加载完毕后会调用 anmi.start();
.setAutoPlayAnimations(true)
.build();
simpleDraweeView.setController(controller);
那我们如果要给 Gif 设置播放次数呢?好像 Fresco 并没有提供类似的 API,那么就需要我们自己去处理了,这里笔者封装好了一个,可以直接复制过去使用:
public class GifController {
private SimpleDraweeView view;
private Uri uri;
private GifListener listener;
private int loopCount = -1;
private int currentCount = 0;
private boolean visibleShowAgain = false;
private boolean hasShow = false;
public abstract static class GifListener{
public abstract void onStart(Animatable anim);
public abstract void onStop(Animatable anim);
public abstract void onRepeat(Animatable anim,int currentCount);
}
public GifController setView(SimpleDraweeView view){
this.view = view;
return this;
}
public GifController setGif(int resId){
Uri uri = new Uri.Builder()
.scheme(UriUtil.LOCAL_RESOURCE_SCHEME)
.path(String.valueOf(resId))
.build();
this.uri = uri;
return this;
}
public GifController setGif(String url){
this.uri = Uri.parse(url);
return this;
}
public GifController setListener(GifListener listener){
this.listener = listener;
return this;
}
public GifController setLoopCount(int loopCount){
this.loopCount = loopCount;
return this;
}
public GifController setVisibleShowAgain(boolean visibleShowAgain){
this.visibleShowAgain = visibleShowAgain;
return this;
}
public void showGif(Context context){
if (view == null || uri == null || context == null){
return;
}
if (!Fresco.hasBeenInitialized()){
Fresco.initialize(context);
}
final DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(uri)
.setControllerListener(new BaseControllerListener<Object>() {
@Override
public void onFinalImageSet(String id, @Nullable Object info, @Nullable final Animatable anim) {
if (anim != null) {
try {
AnimatedDrawable2 drawable = (AnimatedDrawable2) anim;
drawable.setAnimationListener(new BaseAnimationListener() {
@Override
public void onAnimationStart(AnimatedDrawable2 drawable) {
if (listener != null){
listener.onStart(anim);
}
}
@Override
public void onAnimationStop(AnimatedDrawable2 drawable) {
currentCount = 0;
if (listener != null){
listener.onStop(anim);
}
}
@Override
public void onAnimationRepeat(AnimatedDrawable2 drawable) {
currentCount++;
if (listener != null){
listener.onRepeat(anim,currentCount);
}
if (currentCount >= loopCount){
anim.stop();
}
}
});
}catch (Throwable e){
LogUtil.logE(e.getMessage());
}
if (!hasShow || visibleShowAgain){
anim.start();
}
hasShow = true;
}
}
})
.build();
view.setController(controller);
}
}
怎么使用呢?我们直接在 Activity 中调用:
new GifController()
// 设置 Gif 资源,也可以传入 url
.setGif(R.drawable.gif_xxx)
// 设置 Gif 播放回调,包括开始、结束、第几次重复完成
.setListener(new GifController.GifListener() {
@Override
public void onStart(Animatable anim) {
System.out.println("Gif Start");
}
@Override
public void onStop(Animatable anim) {
System.out.println("Gif stop");
}
@Override
public void onRepeat(Animatable anim,int currentCount) {
System.out.println("Gif Repeat"+currentCount);
}
})
// 设置 SimpleDraweeView
.setView(view)
// 设置重复次数
.setLoopCount(1)
// 设置 Gif 在屏幕上再次可见是否再次播放,默认 false
.setVisibleShowAgain(true)
// 展示
.showGif(this);
好了,完成。