Android中显示动画的GIF

首先看看GIF文件的存储结构和动画原理-->[转]GIF图片的文件储存结构和动画原理

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

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

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

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

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

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

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

1 @Override 2 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 3 if (mMovie != null) { 4 int movieWidth = mMovie.width(); 5 int movieHeight = mMovie.height(); 6 /* 7 * Calculate horizontal scaling 8 */ 9 10 float scaleH = 1f; 11 int measureModeWidth = MeasureSpec.getMode(widthMeasureSpec); 12 if (measureModeWidth != MeasureSpec.UNSPECIFIED) { 13 int maximumWidth = MeasureSpec.getSize(widthMeasureSpec); 14 if (movieWidth > maximumWidth) { 15 scaleH = (float) movieWidth / (float) maximumWidth; 16 } 17 } 18 /* 19 * calculate vertical scaling 20 */ 21 22 float scaleW = 1f; 23 int measureModeHeight = MeasureSpec.getMode(heightMeasureSpec); 24 25 if (measureModeHeight != MeasureSpec.UNSPECIFIED) { 26 int maximumHeight = MeasureSpec.getSize(heightMeasureSpec); 27 if (movieHeight > maximumHeight) { 28 scaleW = (float) movieHeight / (float) maximumHeight; 29 } 30 } 31 32 /* 33 * calculate overall scale 34 */ 35 mScale = 1f / Math.max(scaleH, scaleW); 36 37 mMeasuredMovieWidth = (int) (movieWidth * mScale); 38 mMeasuredMovieHeight = (int) (movieHeight * mScale); 39 40 setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight); 41 42 } else { 43 /* 44 * No movie set, just set minimum available size. 45 */ 46 setMeasuredDimension(getSuggestedMinimumWidth(),getSuggestedMinimumHeight()); 47 } 48}

我们知道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 之后不能使用硬件渲染:

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

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

欢迎转载 源博客链接:<a href="http://linkyan.com/2013/10/display-gif/">http://linkyan.com/2013/10/display-gif</a>

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

APNG 那些事

!(https://oscimg.oschina.net/oscnet/c4ad8907b66a37678c655eb00fbacb63c08.jpg)凹凸君: GIF存活29年之久,依然大行其道的今天,有没有更合适的动画格式?回答: 或许,可以聊聊APNG。关于APNGAPNG(AnimatedPor