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

时间: 2024-07-29 10:56:49

fresco gif 时间的相关文章

(Facebook开源项目)Fresco:一个新的Android图像处理类库

在Facebook的Android客户端上快速高效的显示图片是非常重要的.然而多年来,我们遇到了很多如何高效存储图片的问题.图片太大,而设备太小.一个像素点就占据了4个字节数据(分别代表R G B和alpha).如果在一个480*800尺寸的手机屏幕上,一张单独的全屏图片就会占据1.5MB的内存空间.通常手机的内存都非常小,而这些内存被多种多样的app划分占用.在一些设备上,Facebook app虽然只有16MB,但是仅仅一个图片就占用了1/10的空间. 当你的app用完你的内存时会发生什么呢

Fresco源码解析 - 本地编译

第一次写专栏,如有表述不好或者理解错误的地方,请各位读者不吝赐教,本人一定虚心接受并第一时间改正. 作为专题第一篇,先从最简单的开始,顺便找找感觉. Fresco 是 facebook 在今年的 F8 大会上宣布开源的一个用于加载图片的库,它不仅支持多种图片文件格式,而且由于使用了pinned purgeables 技术,使得大图加载过程中产生OOM的概率大大降低,对开发者来说绝对是一件喜大普奔的事情,对于像天猫HD这样需要加载大量图片的APP来说也绝对是个福音. 下载代码 首先把源码从 Git

Fresco 使用笔记(一):加载gif图片并播放

前言: 项目中图文混合使用的太多太多了,但是绝大部分都是静态图片. 然而现在项目开发中有这么一个需求:显示一个出一个简短的动画(一般都不超过3秒)演示 比如说:一个功能提供很多步骤来教用户做广播体操,那么第一步就显示一个3秒钟的动作图,第二步显示一个几秒钟的动作图.(当然这个需求不是这个功能) 怎么解决呢:一确定这个需求我的第一实现思路便是让美工给我搞几个连续的图片,我使用帧动画来轮回播放 便实现了这个动画. 但是帧动画使用起来太复杂了,一套动作我要搞好久来实现.那么就想Android中支持不支

主流图片加载框架ImageLoader、Glide、Picasso、Fresco性能分析---图片加载速度比较

图片加载这种实现繁琐,可复用性又极强的东西,自然是选择使用图片加载框架来快速实现. 像是Android-Universal-Image-Loader.Glide.Picasso.Fresco之类, 但是这时候的烦恼在于,这么多图片加载框架到底谁最实用? 有说Fresco,因为支持WebP,还是用了NDK来加载图片,减少JavaHeap的使用 有Picasso,简洁高效 有说Glide,Picasso升级,可以加载Gif,在Picasso基础上扩展了很多方法 ImageLoader 使用最广,因为

96、facebook Fresco框架库源使用基础

开源项目链接 facebook Fresco仓库:git clone https://github.com/facebook/fresco facebook Fresco主页:“>http://fresco-cn.org/docs/index.html# Fresco Demo:https://github.com/yanbober/Android-Blog-Source/tree/master/Fresco-Android-CN-Demo 背景介绍 最近微博和论坛火了一个facebook的li

Android 图片处理之 Fresco

一.关于 Fresco github: https://github.com/facebook/fresco API: http://www.fresco-cn.org/javadoc/reference/packages.html Fresco 是一个强大的图片加载组件. Fresco 中设计有一个叫做 image pipeline 的模块.它负责从网络,从本地文件系统,本地资源加载图片.为了最大限度节省空间和CPU时间,它含有3级缓存设计(2级内存,1级文件). Fresco 中设计有一个叫

Android之图片加载框架Fresco基本使用(二)

PS:最近看到很多人都开始写年终总结了,时间过得飞快,又到年底了,又老了一岁. 学习内容: 1.进度条 2.缩放 3.ControllerBuilder,ControllerListener,PostProcesser,Image Request 4.渐进式JPEG与动图的显示     最近这两天把Fresco的官方文档算是看了个差不多,就剩下Fresco的基本原理还有结合okHttp等类库如何使用的问题,虽然官方文档给出的功能比较的多,比如说自定义View,缩略图显示等等,这些我也基本就看了个

Android图片加载神器之Fresco,基于各种使用场景的讲解

转载请标明出处:http://blog.csdn.net/android_ls/article/details/53137867 Fresco是Facebook开源Android平台上一个强大的图片加载库,也是迄今为止Android平台上最强大的图片加载库. 优点:相对于其他开源的第三方图片加载库,Fresco拥有更好的内存管理和强大的功能,基本上能满足所有的日常使用场景. 缺点:整体比较大,不过目前的版本已做了拆分,你只需要导入你使用到的功能相关的库.从代码层面来说侵入性太强,体现在要使用它需

【转】Fresco之强大之余的痛楚

http://www.jianshu.com/p/5364957dcf49 开始之前 如果你有使用的心得,技巧,踩坑经历,希望贡献出来,我会在TODO中慢慢添加(^^)/ 关于Fresco Fresco 是一个强大的图片加载组件. Fresco 中设计有一个叫做*image pipeline*的模块.它负责从网络,从本地文件系统,本地资源加载图片.为了最大限度节省空间和CPU时间,它含有3级缓存设计(2级内存,1级文件). Fresco 中设计有一个叫做*Drawees*模块,方便地显示load