fresco gif 时间

Posted wikiki

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了fresco gif 时间相关的知识,希望对你有一定的参考价值。

一、使用的是Fresco的三方库
官网文档:https://www.fresco-cn.org/docs/progress-bars.html
二、支持播放GIF
这里只是介绍支持播放GIF的功能,所以步骤也都是GIF的步骤
1.引入Fresco
为了支持获取GIF播放一遍的时长,就要引入0.13.0以后的版本,但是0.14.0改变了android studio的分包机制,可能会导致编译问题,所以还是选择0.13.0版本。

dependencies {
    compile fileTree(include: [‘*.jar‘], dir: ‘libs‘)
    compile ‘com.facebook.fresco:fresco:0.13.0‘
    compile ‘com.facebook.fresco:animated-gif:0.13.0‘
}

我这里实现了在整个屏幕上添加一个GIF view
2.获取root view

private static ViewGroup getRootGroup(Activity activity) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
            return (ViewGroup) activity.findViewById(android.R.id.content);
        } else {
            return (ViewGroup) activity.getWindow().getDecorView().getRootView();
        }
    }

上面获取rootview
3.new一个SimpleDraweeView(com.facebook.drawee.view.SimpleDraweeView)

SimpleDraweeView gifView = (SimpleDraweeView) activity.findViewById(R.id.gif_tip_view);
if (gifView == null) {
    gifView = new SimpleDraweeView(activity);
    gifView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            //触摸之后的事件不往后传递
            return true;
        }
    });
    gifView.setPadding(0, HtscSystemUtil.getStatusBarHeight(activity), 0, 0);
    // GIF图片填充XY轴
    gifView.getHierarchy().setActualImageScaleType(ScalingUtils.ScaleType.FIT_XY);
    gifView.setId(R.id.gif_tip_view);
}

4.下面就是关键代码了
很多GIF本身都是可以循环播放的,但是我这里想实现GIF播放一遍就停止,然后显示一个自己想要的界面。
从官方文档看到如下信息:

手动控制动画图播放

也许你希望在代码中直接控制动画的播放。这种情况下,你需要监听图片是否加载完毕,然后才能控制动画的播放:

ControllerListener controllerListener = new BaseControllerListener<ImageInfo>() {
    @Override
    public void onFinalImageSet(
        String id,
        @Nullable ImageInfo imageInfo,
        @Nullable Animatable anim) {
        if (anim != null) {
          // 其他控制逻辑
          anim.start();
        }
    }
};

Uri uri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
    .setUri(uri)
    .setControllerListener(controllerListener)
    // 其他设置(如果有的话)
    .build();
mSimpleDraweeView.setController(controller);

另外,controller提供对Animatable 的访问。

如果有可用动画的话,可对动画进行灵活的控制:

Animatable animatable = mSimpleDraweeView.getController().getAnimatable();
if (animatable != null) {
  animatable.start();
  // later
  animatable.stop();
}

所以我的思路如下:
获取GIF播放一遍的时长,播放一遍后,让GIF的animatable停止,并显示想要显示的view。以下是我的代码

ControllerListener controllerListener = new BaseControllerListener<ImageInfo>() {
    @Override
    public void onFinalImageSet(String id, ImageInfo imageInfo, final Animatable animatable) {
        if (animatable != null) {
            int duration = 0;
            try {
                Field field = AbstractAnimatedDrawable.class.getDeclaredField("mTotalLoops");
                field.setAccessible(true);
                field.set(animatable, 1);
            } catch (Exception e) {
                e.printStackTrace();
            }
            animatable.start();
            if (animatable instanceof AbstractAnimatedDrawable) {
                // 只有fresco 0.13.0+才有getDuration()的方法
                duration = ((AbstractAnimatedDrawable) animatable).getDuration();
            }
            if (duration > 0) {
                finalImageView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (animatable.isRunning()) {
                            animatable.stop();
                            rootGroup.removeView(finalImageView);
                            ViewGroup parent;
                            View gifEndView = getGifEndView(type, rootGroup, finalImageView, activity);
                            if ((parent = (ViewGroup) gifEndView.getParent()) != null) {
                                parent.removeView(gifEndView);
                            }
                            rootGroup.addView(gifEndView);
                        }
                    }
                }, duration);
            }
        }
    }
};

DraweeController draweeController = Fresco.newDraweeControllerBuilder()
                    .setUri(Uri.parse(getGifImgRes(type)))//路径
                    .setAutoPlayAnimations(false)
                    .setOldController(gifView.getController())
                    .setControllerListener(controllerListener)
                    .build();
gifView.setController(draweeController);

两点小说明:
(1)GIF只播放一遍(反射)

try {
    Field field = AbstractAnimatedDrawable.class.getDeclaredField("mTotalLoops");
    field.setAccessible(true);
    field.set(animatable, 1);
} catch (Exception e) {
    e.printStackTrace();
}

(2)获取播放一遍的时长

 if (animatable instanceof AbstractAnimatedDrawable) {
    // 只有fresco 0.13.0+才有getDuration()的方法
    duration = ((AbstractAnimatedDrawable) animatable).getDuration();
}

(3)getGifImgRes(type)接口
就是获取资源名的string,比如"asset://com.xxx(包名)/mytestgif.gif"
还支持很多其他的类型
(4)getGifEndView(type, rootGroup, finalImageView, activity)接口
这是播放结束要显示的view,自己随便定义就行了
5.用root view把SimpleDraweeView添加进去

ViewGroup parent;
if ((parent = (ViewGroup) gifView.getParent()) != null) {
    parent.removeView(gifView);
}
rootGroup.addView(gifView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

6.最后一个问题
有没有想法,想要GIF播放过程中停止,比如有个跳过按钮,或者按back键可以跳过?
(1)添加一个跳过按钮

// 添加一个跳过的按钮
                        TextView skipButton = (TextView) activity.findViewById(R.id.gif_tip_skip_bt);
                        if (skipButton == null) {
                            skipButton = new TextView(activity);
                            skipButton.setBackgroundResource(R.drawable.tip_view_skip_bg);
                            skipButton.setText("跳过");
                            skipButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
                            skipButton.setTextColor(activity.getResources().getColor(R.color.white));
                            skipButton.setGravity(Gravity.CENTER);
                            final TextView finalSkipButton = skipButton;
                            skipButton.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    animatable.stop();
                                    rootGroup.removeView(finalSkipButton);
                                    rootGroup.removeView(finalImageView);
                                }
                            });
                            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                            params.gravity = Gravity.TOP | Gravity.RIGHT;
                            params.topMargin = HtscSystemUtil.getStatusBarHeight(activity) + HtscSystemUtil.convertDpToPixel(25);
                            params.rightMargin = HtscSystemUtil.convertDpToPixel(10);
                            params.width = HtscSystemUtil.convertDpToPixel(35);
                            params.height = HtscSystemUtil.convertDpToPixel(20);
                            skipButton.setLayoutParams(params);
                            skipButton.setId(R.id.gif_tip_skip_bt);
                        }
                        ViewGroup parent;
                        if ((parent = (ViewGroup) skipButton.getParent()) != null) {
                            parent.removeView(skipButton);
                        }
                        rootGroup.addView(skipButton);

(2)按下back键停止播放

        SimpleDraweeView gifView = (SimpleDraweeView) activity.findViewById(R.id.gif_tip_view);
            if (gifView != null) {
                DraweeController controller = gifView.getController();
                Animatable anim = null;
                if (controller != null) {
                    anim = controller.getAnimatable();
                    if (anim != null && anim.isRunning()) {
                        anim.stop();
                    }
                }
                rootGroup.removeView(gifView);
            }

参考资料:
Fresco(各种特效)——播放gif
http://blog.csdn.net/yy1300326388/article/details/45057677
Android实现加载GIF图片
http://www.jianshu.com/p/04a6433dd456
安卓中使用fresco加载Gif图片
http://blog.csdn.net/shlock_fan/article/details/50334273

 

以上是关于fresco gif 时间的主要内容,如果未能解决你的问题,请参考以下文章

使用 Fresco 时如何将图像保存到 SD 卡?

Fresco

Fresco SimpleDraweeView 加载相同图片时闪烁的问题分析

NoSuchFieldError

android gradle 依赖项配置变更

怎么把视频转成gif