在实际的Android开发过程中,我们往往会使用到帧动画
一般我们都是采用xml的方式去播放帧动画的
现在这里提供一种新的方式
来实现对帧动画的播放
首先需要用到我自己封装的一个工具类
具体代码如下
public class AnimUtils {
private int[] resIdArr;
private int index;
private View view;
private int period;//动画间隔
private boolean isRepeatFlag = false;
// private boolean isStopFlag = false;
private boolean isStartFlag = false;
private final static int PARSE_BITMAP_MSG = 0;
private static HandlerThread sHandlerThread = new HandlerThread("anim-workThread");
private static Handler sWorkHandler;
static {
sHandlerThread.start();
sWorkHandler = new Handler(sHandlerThread.getLooper()) {
public void handleMessage(Message msg) {
Log.e("lugx", "2019-4-19 sWorkHandler Handler msg=" + msg.what);
if (msg.what == PARSE_BITMAP_MSG) {
if (msg.obj instanceof Request) {
Request request = (Request) msg.obj;
request.returnFun();
}
}
}
};
}
static class Request {
final Resources resource;
final int resId;
final Handler handler;
final int msgWhat;
public Request(Resources resource, int resId, Handler handler, int msgWhat) {
this.resource = resource;
this.resId = resId;
this.handler = handler;
this.msgWhat = msgWhat;
}
public void returnFun() {
Bitmap bitmap = BitmapFactory.decodeResource(resource, resId);
Message msg = Message.obtain();
msg.what = msgWhat;
msg.obj = bitmap;
handler.sendMessage(msg);
}
}
public interface OnAnimEndListener {
public void onAnimEnd();
}
private OnAnimEndListener listener;
//播放完成监听
public void setOnAnimEndListener(OnAnimEndListener listener) {
this.listener = listener;
}
private final static int PLAYING_ANIM_MSG = 0;
private final static int GET_BITMAP_MSG = 1;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Log.e("lugx", "2019-4-19 main Handler msg=" + msg.what);
switch (msg.what) {
case PLAYING_ANIM_MSG: {
sWorkHandler.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if (resIdArr.length<=index){
return;
}
final Bitmap bitmap = BitmapFactory.decodeResource(view.getResources(),
resIdArr[index]);
Message msg = Message.obtain();
msg.what = GET_BITMAP_MSG;
msg.obj = bitmap;
handler.sendMessage(msg);
}
});
// Request request = new Request(view.getResources(), resIdArr[index],
// handler, GET_BITMAP_MSG);
// Message requestMsg = Message.obtain();
// requestMsg.what = PARSE_BITMAP_MSG;
// requestMsg.obj = request;
// sWorkHandler.sendMessage(requestMsg);
break;
}
case GET_BITMAP_MSG: {
if (!isStartFlag) {
Log.e("lugx", "2019-4-19 main Handler stop *** " + view);
return;
}
Bitmap bitmap = (Bitmap) msg.obj;
BitmapDrawable bd = new BitmapDrawable(view.getResources(), bitmap);
view.setBackground(bd);
// Log.d("print", "宽是: "+view.getWidth());
// view.setBackground(bd);
index++;
if (index >= resIdArr.length) {
if (isRepeatFlag) {
index = 0;
} else {
if (listener != null) {
listener.onAnimEnd();
}
return;
}
}
handler.sendEmptyMessageDelayed(PLAYING_ANIM_MSG, getDelay(period));
break;
}
}
}
};
//
private long getDelay(long delayTime) {
if (delayTime <= 0) {
return 0;
} else if (delayTime < 2) {
return delayTime;
} else {
return delayTime - 1;
}
}
public AnimUtils() {
index = 0;//第几章图片
}
/**
* @param view 控件
* @param resIdArr 图片素材
* @param isRepeatFlag 是否循环播放
*/
public void setAnimInfo(View view, int[] resIdArr, boolean isRepeatFlag) {
this.view = view;
this.resIdArr = resIdArr;
this.isRepeatFlag = isRepeatFlag;
}
/**
*
* @param delayMillis 延时
* @param period 一帧持续时间
*/
public void startAnim(long delayMillis, int period) {
this.period = period;
index = 0;
handler.removeMessages(PLAYING_ANIM_MSG);
handler.sendEmptyMessageDelayed(PLAYING_ANIM_MSG, getDelay(delayMillis));
isStartFlag = true;
}
/**
* 是否正在播放
*
* @return
*/
public boolean isAniming() {
return isStartFlag;
}
//是否循环
public boolean isRepeat() {
return isRepeatFlag;
}
public void stopAnim() {
isStartFlag = false;
if (handler.hasMessages(PLAYING_ANIM_MSG)) {
Log.e("lugx", "2019-4-19 main Handler stopAnim " + view);
}
handler.removeMessages(PLAYING_ANIM_MSG);
//view.setBackgroundResource(resIdArr[0]);
}
//应用退出
public static void quit() {
sHandlerThread.quit();
}
}
使用起来也很简单
AnimUtils animUtil=new AnimUtils();
animUtil.setAnimInfo(exitimg,AnimDrawable.chansha,true);
animUtil.startAnim(0,10);
这里大概介绍下这两个方法
setAnimInfo():第一个参数为播放动画的控件,第二个参数为int类型的数组,用来对资源进行索引,第三个表示是否重复播放
startAnim():第一个参数代表延时多少毫秒播放,第二个表示帧动画之间每一帧的时间间隔
至于其他的方法,比如暂停,判断是否循环播放等
可以直接在上面的工具类中找到
这里就不一一介绍了
最后,你也可以改造这份代码
比如这里是通过更改View的background来实现播放动画
你可以传入一个imageview
去更改他的src属性来实现播放动画
总体来看还是比较灵活的。
这个工具类的好处是使用完了之后
可以实现对内存的回收
不会因为帧动画太大导致内存溢出
好了就介绍到这里了,谢谢大家!