- 帧动画就是顺序播放一组预先定义好的图片,就类似于我们观看视频,就是一张一张的图片连续播放。
- 帧动画的使用很简单,总共就两个步骤:
1、在res/drawable目录下定义一个XML文件,根节点为系统提供的animation-list,然后放入定义更好的图片;
2、使用AnimationDrawable类播放第一步定义好的Drawable中的图片,形成动画效果;
xml定义资源
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/image01" android:duration="500"/>
<item android:drawable="@drawable/image02" android:duration="500"/>
<item android:drawable="@drawable/image03" android:duration="500"/>
</animation-list>
// android:oneshot=“false”: 表示是否重复播放动画,还是只播放一次;
// 每个item都有Drawable和duration属性,Drawable表示我们要播放的图片;duration表示这张图播放的时间;
java 代码创建
imageView_2 = findViewById(R.id.image_2);
AnimationDrawable animationDrawable1 = new AnimationDrawable();
animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_1 ),200);
animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_2 ),200);
animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_3 ),200);
animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_4 ),200);
animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_5 ),200);
animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_6 ),200);
animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_7 ),200);
animationDrawable1.addFrame(getResources().getDrawable(R.drawable.iron_8 ),200);
animationDrawable1.setOneShot(true);
imageView_2.setImageDrawable(animationDrawable1);
animationDrawable1.start();
运行
Button button = (Button) findViewById(R.id.bt_001);
button.setBackgroundResource(R.drawable.frame_animation);//把Drawable设置为button的背景
//拿到这个我们定义的Drawable,实际也就是AnimationDrawable
AnimationDrawable animationDrawable = (AnimationDrawable) button.getBackground();
animationDrawable.start();//开启动画
AnimationDrawable
- AnimationDrawable继承自Drawable。
- AnimationDrawable会一次性把所有图片加载到内存中。
我们是通过xml文件保存帧动画信息的,所以从Drawable.createFromXml()方法看起:
构造函数
public AnimationDrawable() {
this(null, null);
}
private AnimationDrawable(AnimationState state, Resources res) {
final AnimationState as = new AnimationState(state, this, res);
setConstantState(as);
if (state != null) {
setFrame(0, true, false);
}
}
AnimationState
private final static class AnimationState extends DrawableContainerState {
private int[] mDurations; // 保存图片资源的
private boolean mOneShot = false; // 是否显示一次 控制循环播放动画
// 添加一帧图片
public void addFrame(Drawable dr, int dur) {
// Do not combine the following. The array index must be evaluated before
// the array is accessed because super.addChild(dr) has a side effect on mDurations.
int pos = super.addChild(dr);
mDurations[pos] = dur;
}
}
start() 开启动画
@Override
public void start() {
mAnimating = true;
if (!isRunning()) {
// Start from 0th frame.
setFrame(0, false, mAnimationState.getChildCount() > 1 || !mAnimationState.mOneShot);
}
}
private void setFrame(int frame, boolean unschedule, boolean animate) {
// 当前frame是否超过了现实的范围
if (frame >= mAnimationState.getChildCount()) {
return;
}
mAnimating = animate;
mCurFrame = frame;
selectDrawable(frame);
if (unschedule || animate) {
unscheduleSelf(this);
}
if (animate) {
// Unscheduling may have clobbered these values; restore them
mCurFrame = frame;
mRunning = true;
scheduleSelf(this, SystemClock.uptimeMillis() + mAnimationState.mDurations[frame]);
}
}
网友评论