首先看看GIF文件的存储结构和动画原理–>[[转]GIF图片的文件储存结构和动画原理](http://blog.sina.com.cn/s/blog_571296860100jvhz.html)

以及已知的两种解决方案–>Android & how to use animated GIF

Github上还算可以的开源项目–>gif-movie-view

但实际使用的时候,还是有些小问题,比如

我们的GIF不全是本地已经存在的,可能是从文件加载,或者是网络下载的,这时候在使用Movie.decodeStream(InputStream is)时会遇到

  • IOException on Movie.decodeFile() - android
  • IOException - Cannot load file

我的做法是统一使用Movie.decodeByteArray(byte[] b) 类方法,可以避免很多麻烦,下载 gif-movie-view
项目,并在GifMovieView中添加

public void setMovieByteArray(byte[] bb) {    mMovie = Movie.decodeByteArray(bb, 0, bb.length);    requestLayout();}

假如我们显示GIF的时候是异步的,那么在还没有显示时,GifMovieView不占据任何空间,完成加载后整个界面会重绘,因为GifMovieView重载的onMeasure()函数是这样子的:

 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    if (mMovie != null) {        int movieWidth = mMovie.width();        int movieHeight = mMovie.height();        /*         * Calculate horizontal scaling         */        float scaleH = 1f;        int measureModeWidth = MeasureSpec.getMode(widthMeasureSpec);        if (measureModeWidth != MeasureSpec.UNSPECIFIED) {            int maximumWidth = MeasureSpec.getSize(widthMeasureSpec);            if (movieWidth > maximumWidth) {                scaleH = (float) movieWidth / (float) maximumWidth;            }        }        /*         * calculate vertical scaling         */        float scaleW = 1f;        int measureModeHeight = MeasureSpec.getMode(heightMeasureSpec);        if (measureModeHeight != MeasureSpec.UNSPECIFIED) {            int maximumHeight = MeasureSpec.getSize(heightMeasureSpec);            if (movieHeight > maximumHeight) {                scaleW = (float) movieHeight / (float) maximumHeight;            }        }        /*         * calculate overall scale         */        mScale = 1f / Math.max(scaleH, scaleW);        mMeasuredMovieWidth = (int) (movieWidth * mScale);        mMeasuredMovieHeight = (int) (movieHeight * mScale);        setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight);    } else {        /*         * No movie set, just set minimum available size.    */    setMeasuredDimension(getSuggestedMinimumWidth(),getSuggestedMinimumHeight());    }}

我们知道setMeasuredDimension(int width,int height);将指定View在父容器里占据的width,和height,假如你们的业务逻辑在得到GIF文件的URL同时,还能获得它的width和height,并且这里你不希望调用requestLayout()函数重绘,做了如下修改

setMeasuredDimension(mWidth,mHeight);  //mWidth, mHeight 是已知Gif的宽高

这个时候可能连显示也不正常了! 可能是因为父容器判断GifMovieView大小并没有发生改变,这样的话就不调用onLayout() 和 onDraw() 函数,也就没有开始GIF的动画循环,所以就是一片空白. 有待考证.

另外还有些注意点 比如API 11 之后不能使用硬件渲染:

 /*** Starting from HONEYCOMB have to turn off HW acceleration to draw* Movie on Canvas.    */    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {        setLayerType(View.LAYER_TYPE_SOFTWARE, null);    }

总结:
Movie的坑还是很多的,不像成品类库,相对于WebView来显示GIF的优势是轻量级,更易管理.

欢迎转载 源博客链接:http://linkyan.com/2013/10/display-gif

更多相关文章

  1. Android(安卓)Studio文件分组插件
  2. Android(安卓)Studio 快捷键(2)
  3. Android查看Apk签名
  4. android ActionBar用法详解
  5. android设置显示语言
  6. 自定义android的tab样式 《》
  7. Android中InCallUI显示太慢问题分析
  8. 一些安卓的基本权限 清单配置文件
  9. 如何将编译好的apk文件加入Android系统?

随机推荐

  1. android 常用JVM配置参数
  2. webView去掉右侧导航条
  3. android之android.os.NetworkOnMainThrea
  4. Android执行命令行命令(获取系统Logcat)
  5. android面试与总结
  6. Android - 设置带滚动条的TextView
  7. Android EditText输入的一些限制
  8. Android(安卓)ListView拖动时背景颜色会
  9. Android 源码 修改系统默认横屏
  10. A3```在android native c里打log