需求:限制GIF播放次数
解决方案:
1.无播放结束监听
Glide.with(this).asGif().load(gifUrl).into(new GlideDrawableImageViewTarget(imageview, N)) ;//N为播放次数
2.添加播放结束监听
public static void loadOneTimeGif(Context context, Object model, final ImageView imageView,int num, final GifListener gifListener) {
Glide.with(context).load(model)
.listener(new RequestListener<Integer, GlideDrawable>() {
@Override
public boolean onException(Exception arg0, Integer arg1, Target<GlideDrawable> arg2, boolean arg3) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, Integer model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
// 计算动画时长
GifDrawable drawable = (GifDrawable) resource;
GifDecoder decoder = drawable.getDecoder();
int duration = 0;
for (int i = 0; i < drawable.getFrameCount(); i++) {
duration += decoder.getDelay(i);
}
imageView.postDelayed(new Runnable() {
@Override
public void run() {
if (gifListener != null) {
gifListener.gifPlayComplete();
}
}
}, duration*num);
return false;
}
}) //仅仅加载一次gif动画
.into(new GlideDrawableImageViewTarget(imageview, num));
}
/**
* Gif播放完毕回调
*/
public interface GifListener {
void gifPlayComplete();
}
在Glide4.x的解决方案:
在Glide4.x中,我们没法再直接获取GifDecoder对象了,原因是因为GlideDrawable不再提供这个方法了。需要采用反射的方法获取到GifDecoder变量,具体代码如下:
public static void loadOneTimeGif(Context context, Object model, final ImageView imageView,int num, final GifListener gifListener) {
Glide.with(context).asGif().load(model).listener(new RequestListener<GifDrawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<GifDrawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
try {
Field gifStateField = GifDrawable.class.getDeclaredField("state");
gifStateField.setAccessible(true);
Class gifStateClass = Class.forName("com.bumptech.glide.load.resource.gif.GifDrawable$GifState");
Field gifFrameLoaderField = gifStateClass.getDeclaredField("frameLoader");
gifFrameLoaderField.setAccessible(true);
Class gifFrameLoaderClass = Class.forName("com.bumptech.glide.load.resource.gif.GifFrameLoader");
Field gifDecoderField = gifFrameLoaderClass.getDeclaredField("gifDecoder");
gifDecoderField.setAccessible(true);
Class gifDecoderClass = Class.forName("com.bumptech.glide.gifdecoder.GifDecoder");
Object gifDecoder = gifDecoderField.get(gifFrameLoaderField.get(gifStateField.get(resource)));
Method getDelayMethod = gifDecoderClass.getDeclaredMethod("getDelay", int.class);
getDelayMethod.setAccessible(true);
//设置播放次数
resource.setLoopCount(num);
//获得总帧数
int count = resource.getFrameCount();
int delay = 0;
for (int i = 0; i < count; i++) {
//计算每一帧所需要的时间进行累加
delay += (int) getDelayMethod.invoke(gifDecoder, i);
}
imageView.postDelayed(new Runnable() {
@Override
public void run() {
if (gifListener != null) {
gifListener.gifPlayComplete();
}
}
}, delay*num);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return false;
}
}).into(imageView);
}
/**
* Gif播放完毕回调
*/
public interface GifListener {
void gifPlayComplete();
}