您现在的位置是:首页 >  编程分享 > EXPERIENCEEXPERIENCE

Glide4.0以后监听Gif播放完成

TCTW 转载 编程分享 2017-05-20

简介 lideDrawable;  GifDecoder decoder = drawable.getDe


在Glide3.0的时候,我们可以通过GifDecoder获取每一帧的播放时长然后相加得到gif的播放时长,即:

  GifDrawable drawable = (GifDrawable) glideDrawable;
 GifDecoder decoder = drawable.getDecoder();
 long duration = 0;
 for (int i = 0; i < drawable.getFrameCount(); i++) {
         duration += decoder.getDelay(i);
}

然后使用handle 发送一个延时消息,或者其它方法,等gif播放完成以后再做相应操作。

或者,通过重写GifDrawable,重写onStop()方法来处理:

  public  class MyGifDrawable extends GifDrawable {

        public MyGifDrawable (GifDrawable other) {
            this(other, other.getFirstFrame(), other.getFrameTransformation());
        }

        @Override
        public void stop() {
            super.stop();

            //GIF播放完成,可以做一些操作
        }
    }

但是到Glide4.0, GifDecoder 被声明为private,去掉了getDecoder()方法,第一种方法如果不使用反射,是无法做到的。

这时我们可以去重写GifDrawable,MyGifDrawable 继承自GifDrawable,然后我们去获GifDrawable里边存储的gif的数据,然后重新初始化一个GifDecoder,使用这个GifDecoder重新new 一个MyGifDrawable ,在MyGifDrawable 的stop方法中监听gif播放完成的时机。

  public  class MyGifDrawable extends GifDrawable {

public MyGifDrawable (Context context, GifDecoder bitmapProvider, Transformation<Bitmap> frameTransformation, int targetFrameWidth, int targetFrameHeight, Bitmap firstFrame) {
            super(context, bitmapProvider, frameTransformation, targetFrameWidth, targetFrameHeight, firstFrame);
        }

        @Override
        public void stop() {
            super.stop();

            //这里之所以要判断callBack是否为null,是因为在RecycleView中当gif划出屏幕,然后再划入屏幕时,callback会为null,

           //在GifDrawable中的onFrameReady()方法,会判断如果callback为null,会直接会调用onstop方法,当gif图在recycleview中,划出//屏幕再划入屏幕时,callback会为null,这是就会出现,当第一帧刚准备好显示出来,就会马上调用onstop()方法,为避免这种情况,在此加入//下方这个判断。

           if (getCallback() != null) {
                     //GIF播放完成,可以做一些操作
            }
        }


    }

可以在Glide的RequestListener中的onResourceReady中拿到glide解析好的gifDrawable,来调用以下方法初始化我们自己定义的GifDrawable

 public static MyGifDrawable initMyGifDrawable(Context context, GifDrawable gifDrawable) {
        GifBitmapProvider provider = new GifBitmapProvider(Glide.get(context).getBitmapPool());
        Transformation transformation = gifDrawable.getFrameTransformation();
        if (transformation == null) {
            transformation = new CenterCrop();
        }
        ByteBuffer byteBuffer = gifDrawable.getBuffer();
        StandardGifDecoder decoder = new StandardGifDecoder(provider);
        decoder.setData(new GifHeaderParser().setData(byteBuffer).parseHeader(),byteBuffer);
        Bitmap bitmap = gifDrawable.getFirstFrame();
        if (bitmap == null) {
            decoder.advance();
            bitmap = decoder.getNextFrame();
        }
        return new MyGifDrawable(context, decoder, transformation, 0, 0, bitmap);
    }

当然也可以使用以下方法来通过Glide拿到图片的二进制数组,来初始化MyGifDrawable :

    // target.get() 必须放到子线程中执行,方法中未做处理,所以此方法必须在子线程中执行
    public static MyGifDrawable loadGif(final Context context, final String url, final RequestOptions options) {
        byte[] data = null;
        FutureTarget<byte[]> target = Glide.with(context)
                .as(byte[].class)
                .load(url)
                .apply(options)
                .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
        try {
            data = target.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return initMyGifDrawable(context, data);
    }

    public static MyGifDrawable initMyGifDrawable(Context context, byte[] data) {
        if (data == null) {
            return null;
        }
        GifBitmapProvider provider = new GifBitmapProvider(Glide.get(context).getBitmapPool());
        Transformation transformation = new CenterCrop();
        StandardGifDecoder decoder = new StandardGifDecoder(provider);
        decoder.read(data);
        decoder.advance();
        Bitmap bitmap = decoder.getNextFrame();
        return new MyGifDrawable(context, decoder, transformation, 0, 0, bitmap);
    }

 

最后拿到MyGifDrawable的对象后,可以调用setLoopCount() 来设置循环次数,调用start()方法开始gif的播放

原地址:https://my.oschina.net/u/3364122/blog/1831883

Tags:


本篇评论 —— 揽流光,涤眉霜,清露烈酒一口话苍茫。


    声明:参照站内规则,不文明言论将会删除,谢谢合作。


      最新评论



ABOUT ME

Name:袅袅牧童 | Arkin

Job:Web全栈技术工程师

WeChat:nnmutong

Email:nnmutong@icloud.com

标签云