Android 实现支持gif的 组件,并可以控制带下,位置。索罗的一下网上的方法,简单的实现了下。
方法1、使用Movie解析gif 流
也是本文使用的方法。 有很多博客介绍是想方法的,过程不难。 有几个问题需要考虑:1如何控制新组件大小;2如何控制 gif 动图大小;3如何控制gif在组件中的位置。
本文会一一介绍方法 这里先贴出源码:https://github.com/HandsomeL/android_gif_imageview
方法2、解析gif得到位图
使用单独的线程管理切换,这种方法也实现过,感觉对于内存消耗还是比较大的,播放起来没有想象中的那么流畅。
一、首先,GifImageView 继承自 ImageView,兼容ImageView的所有方法及属性。
使用Movie 读取gif 的InputStream,在Ondraw() 里面判断是静态图片还是动态图,调用不同的绘画方。
如果是静态图,丢给super,否则调用动图绘制方法 playMovie(canvas);
本文添加了控制机制,选中时才播放,非选中状态显示第一张。
代码:
protected void onDraw(Canvas canvas) {
if (mMovie == null) {
// src is classical imageView;
super.onDraw(canvas);
} else {
int saveCount = canvas.getSaveCount();
if (mDrawMatrix != null && !mDrawMatrix.isIdentity()) {
canvas.concat(mDrawMatrix);
}
if (isSelected()) {
playMovie(canvas);
invalidate();
} else {
mMovie.setTime(0);
mMovie.draw(canvas, 0, 0);
}
canvas.restoreToCount(saveCount);
}
}
playMovie(canvas); 方法代码:
注释放在代码里:
private boolean playMovie(Canvas canvas) {
long now = SystemClock.uptimeMillis();// 获取相对好时间
if (mStartTime == 0) {
mStartTime = now;
}
int duration = mMovie.duration();
if (duration == 0) {
duration = 1000;
}
int relTime = (int) ((now - mStartTime) % duration);//计算相对于开始播放的时间,用来确定需要绘制的图片位置
mMovie.setTime(relTime);//设置相对位置
mMovie.draw(canvas, 0, 0);// 绘制
if ((now - mStartTime) >= duration) {//完成一次播放,返回true,程序使用,请忽略
mStartTime = 0;
return true;
}
return false;
}
本文使用矩阵经行相关处理。代码叫简单,基本都能看懂。
不熟悉矩阵运算的请猛戳这里:http://www.apkbus.com/forum.php?mod=viewthread&tid=58458
private void calculateMatrix(){
if (mMovie == null) {
return;
}
int movieWidth = mMovie.width();// 实际像素宽高
int movieHeight = mMovie.height();
int vWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
int vHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
mDrawMatrix = new Matrix();
float scale;
scale = Math.min((float) vWidth / (float) movieWidth, (float) vHeight / (float) movieHeight);
float dx = (int) ((vWidth - movieWidth * scale) * 0.5f + 0.5f);
float dy = (int) ((vHeight - movieHeight * scale) * 0.5f + 0.5f);
mDrawMatrix.setScale(scale, scale); // 设置缩放
mDrawMatrix.postTranslate(dx, dy); // 设置平移
}
自己的程序没有使用自定义属性,直接通过setGif 设置进去的。如果需要可以参考源码里面的实现方式。
表达有不精指出还望指出~