我的视频课程:《FFmpeg打造Android万能音频播放器》
我们都知道在Android中播放gif控件是很困难的,所以美工经常给我们拆分好了的Gif图片,我们就用循环来展示图片,达到播放Gif的效果。一起我实现播放Gif效果是在xml文件里设置的图片,虽然能实现播放效果,但是不是很好控制,所以今天决定写一个自定义的GIFView来实现Gif播放效果。
先看效果吧,后面有源码下载:
实现这个功能其实挺简单的,就是在自定义View中把设置的图片源,按一定的时间间隔有序的绘制到View上,就实现了这个功能。
代码如下:
package com.ywl5320.gifviewdemo.customview;
import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Toast;
/**
* 循环播放图片
*
* @author ywl
*
*/
public class GifView extends View {
private ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>();
private Bitmap bitmap; // 当前播放的图片
private Paint paint;
private int currentIndex = 0; // 当前播放图片索引
private boolean isStart = false;
private Context context;
private int size = 0; // 播放图片的数量
private int time = 100;// 播放间隔时间毫秒
public GifView(Context context) {
super(context, null);
}
public GifView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
this.context = context;
paint = new Paint();
paint.setAntiAlias(true);
}
// 设置勃发图片源
public void setBitmaps(ArrayList<Bitmap> bitmaps) {
this.bitmaps = bitmaps;
if (this.bitmaps != null && this.bitmaps.size() > 0) {
this.bitmap = this.bitmaps.get(0);
size = this.bitmaps.size();
}
}
// 设置view显示大小为图片大小加padding值
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = 0;
int height = 0;
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int modleWidth = MeasureSpec.getMode(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
int modleHeight = MeasureSpec.getMode(heightMeasureSpec);
if (modleWidth == MeasureSpec.EXACTLY) {
width = sizeWidth;
} else {
if (bitmap != null) {
width = getPaddingLeft() + getPaddingRight()
+ bitmap.getWidth();
} else {
width = getPaddingLeft() + getPaddingRight();
}
}
// 计算高度
if (modleHeight == MeasureSpec.EXACTLY) {
height = sizeHeight;
} else {
if (bitmap != null) {
height = getPaddingTop() + getPaddingBottom()
+ bitmap.getHeight();
} else {
height = getPaddingTop() + getPaddingBottom();
}
}
setMeasuredDimension(width, height);
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
if (this.bitmap != null && this.bitmaps.size() > 0) {
Bitmap tmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawBitmap(tmp, 0, 0, paint);
}
}
// 设置播放时间间隔
public void setTime(int time) {
this.time = time;
}
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
invalidate();
currentIndex++;
bitmap = bitmaps.get(currentIndex % size);
handler.postDelayed(this, time);
}
};
/**
* 开始播放
*/
public void startGif() {
if (this.bitmaps == null || this.bitmaps.size() == 0) {
Toast.makeText(context, "请设置图片源", Toast.LENGTH_SHORT).show();
}
else if (!isStart) {
isStart = true;
currentIndex++;
handler.postDelayed(runnable, time);
}
}
/**
* 暂停播放
*/
public void stopGif() {
isStart = false;
currentIndex = 0;
handler.removeCallbacks(runnable);
}
}
使用方法也很简单,初始化控件(长宽可以为包裹)、设置图片源、设置播放时间间隔然后播放就行了,具体代码不写了,源码中大家可以看到。