利用SurfaceView实现帧动画效果
在开发Android做动画效果的时候,有时候UI给开发一组动画实现的帧图片,如果说图片较少(十几张)、分辨率较低(几K,十几K),用帧动画实现应该没什么问题,但是如果有几十上百张、或者几百K或者上M的图片,这个时候用帧动画来实现其实就很有问题了,内存吃紧,会卡顿,OOM等问题随之而来。
当然如果可以沟通UI改设计是最好的,但是如果非得这样做不可呢?本人就遇到过这样的需求,而且还有好几种不同的图片根据状态连续来回的切换动画,这个时候还要考虑切换的时候不卡顿的问题,之前写过一篇博客利用Handler来一帧帧的去绘制,目前没有发现什么问题,也很流畅,但是不断的发送Handler消息还是有一定弊端的,所以这里带来更优的选择,用SurfaceView来加载图片,因为这个控件是另开子线程利用双缓存加载资源再直接绘制Surface上,不影响主线程,还避过了大部分java层的耗时操作。因此此选择更优。
具体代码实现如下:
注意一下,如果是png带透明背景的图片,需要surfaceView透明背景的实现:
//设置透明背景
//setZOrderOnTop(true) 必须在setFormat方法之前,不然png的透明效果不生效
setZOrderOnTop(true);
mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
public class SurfaceViewAnimation extends SurfaceView implements SurfaceHolder.Callback, Runnable {
private String TAG = "SurfaceViewAnimation";
private SurfaceHolder mSurfaceHolder;
private boolean mIsThreadRunning = true; // 线程运行开关
public static boolean mIsDestroy = false;// 是否已经销毁
private int[] mBitmapResourceIds;// 用于播放动画的图片资源id数组
private int totalCount;//资源总数 用来判断动画循环
private Canvas mCanvas; // 画图片
private Bitmap mBitmap;// 显示的图片的bitmap
private int mCurrentIndext;// 当前动画播放的位置
private int mGapTime = 50;// 每帧动画持续存在的时间
private boolean mIsRepeat = false;
private OnFrameFinishedListener mOnFrameFinishedListener;// 动画监听事件
private Thread thread;
Rect mSrcRect, mDestRect;
public SurfaceViewAnimation(Context context) {
this(context, null);
initView();
}
public SurfaceViewAnimation(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();
}
public SurfaceViewAnimation(Context context, AttributeSet attrs) {
this(context, attrs, 0);