接上一篇文章Android动画之一:Tween Animation(补间动画)示例详解,我们继续学习下Frame Animation(帧动画)的特点及使用。
Frame Animation(帧动画、逐帧动画),又叫做Drawable Animation(绘图动画),它是一系列图片按照一定顺序展示的过程,和放幻灯片相似。它和补间动画一样,实际上也属于View Animation(视图动画),可以用编码实现,也可以定义在Xml中。下面介绍下这两种方式的实现过程及效果。
不管哪种方式实现帧动画,都需要我们事先把图片准备好。因此,我们需要将图片放入drawable文件夹(根据名字也可以猜到放在哪了),然后就可以写代码实现帧动画了。
第一步,把冰箱门打开,错了,是获取一个AnimationDrawable实例并为其添加每一帧动画图片,将其设置为ImageView的背景,在Activity onCreate()的时候你就可以做这件事了。
/**
* 1 通过代码添加帧动画
*/
private void initAnimationDrawable1() {
// 创建AnimationDrawable实例
mAnimationDrawable = new AnimationDrawable();
// 为AnimationDrawable实例添加每一帧动画(这里投机取巧了,可能会有问题)
int startDrawableId = R.drawable.img00;
for (int i = 0; i < 25; i++) {
mAnimationDrawable.addFrame(getResources().getDrawable(startDrawableId + i), 50);
}
// 设置成循环播放
mAnimationDrawable.setOneShot(false);
mImageView.setBackground(mAnimationDrawable);
}
第二步,可以在点击播放按钮的时候去播放动画了,划重点mAnimationDrawable.start(),不好意思划错了
/**
* 播放帧动画
*/
public void playAnimation(View view) {
// 解决点击播放完成后再次点击不播放动画的问题
if (mAnimationDrawable != null) {
long animTotalDuration = (long) getFrameAnimTotalDuration(mAnimationDrawable);
long elapseTime = System.currentTimeMillis() - mAnimationLastStartTime;
if (elapseTime > animTotalDuration && mAnimationDrawable.isRunning()) {
mAnimationDrawable.stop();// 帧动画播放完成后必须调用stop() isRunning()才为false
}
} else {
return;
}
if (!mAnimationDrawable.isRunning()) {
Log.i(TAG, "playAnimation: start");
mAnimationDrawable.start();
mAnimationLastStartTime = System.currentTimeMillis();
} else {
Log.i(TAG, "playAnimation: mAnimationDrawable = " + mAnimationDrawable + "; "
+ "!mAnimationDrawable.isRunning() = " + !mAnimationDrawable.isRunning());
}
}
第三步,可以在播放过程中点击暂停按钮的时候去暂停动画了,划重点mAnimationDrawable.stop()
/**
* 停止帧动画
*/
public void pauseAnimation(View view) {
if (mAnimationDrawable != null && mAnimationDrawable.isRunning()) {
mAnimationDrawable.stop();
} else {
Log.i(TAG, "pauseAnimation: mAnimationDrawable = " + mAnimationDrawable + "; "
+ "mAnimationDrawable.isRunning() = " + mAnimationDrawable.isRunning());
}
}
恩,就是这么简单,你就把大象装进冰箱里了。不好意思,忘记一段代码,开下门。
/**
* 获取帧动画总时长
* @return 帧动画总时长
*/
public int getFrameAnimTotalDuration(AnimationDrawable animationDrawable) {
int frameAnimTotalDuration = 0;
for (int i = 0; i < animationDrawable.getNumberOfFrames(); i++) {
frameAnimTotalDuration += animationDrawable.getDuration(i);
}
return frameAnimTotalDuration;
}
关于帧动画开始、结束的监听,哪位同学有更官方的方式吗?我这自己琢磨的,可能不靠谱。
Xml方式就更简单了,就写xml呗,Follow me!
右键res文件夹>New>Android Resource File>出现New Resource File对话框,File name自定义(如frame_animation_list)、Resource Type选择Drawable、Root element输入animation-list,OK后drawable文件夹下就多出了一个xml文件咯。
然后,像我一样把Xml文件写一下。注意,item的顺序就是播放顺序,不要乱搞哦(不会根据文件名排序吗?恩,你想多了)
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true"><!--oneshot:是否循环播放-->
<item
android:drawable="@drawable/img00"
android:duration="50" />
<item
android:drawable="@drawable/img01"
android:duration="50" />
<item
android:drawable="@drawable/img02"
android:duration="50" />
<item
android:drawable="@drawable/img03"
android:duration="50" />
<item
android:drawable="@drawable/img04"
android:duration="50" />
<item
android:drawable="@drawable/img05"
android:duration="50" />
<item
android:drawable="@drawable/img06"
android:duration="50" />
<item
android:drawable="@drawable/img07"
android:duration="50" />
<item
android:drawable="@drawable/img08"
android:duration="50" />
<item
android:drawable="@drawable/img09"
android:duration="50" />
<item
android:drawable="@drawable/img10"
android:duration="50" />
<item
android:drawable="@drawable/img11"
android:duration="50" />
<item
android:drawable="@drawable/img12"
android:duration="50" />
<item
android:drawable="@drawable/img13"
android:duration="50" />
<item
android:drawable="@drawable/img14"
android:duration="50" />
<item
android:drawable="@drawable/img15"
android:duration="50" />
<item
android:drawable="@drawable/img16"
android:duration="50" />
<item
android:drawable="@drawable/img17"
android:duration="50" />
<item
android:drawable="@drawable/img18"
android:duration="50" />
<item
android:drawable="@drawable/img19"
android:duration="50" />
<item
android:drawable="@drawable/img20"
android:duration="50" />
<item
android:drawable="@drawable/img21"
android:duration="50" />
<item
android:drawable="@drawable/img22"
android:duration="50" />
<item
android:drawable="@drawable/img23"
android:duration="50" />
<item
android:drawable="@drawable/img24"
android:duration="50" />
</animation-list>
代码当然还是要加一点的哦,只需要更改第一步的代码就行了,播放暂停动画就不用动了。
/**
* 2 通过xml添加帧动画,两种方法差别不大
* 2.1 通过xml添加帧动画-方法1
*/
private void initAnimationDrawable2() {
// 通过帧动画资源文件(frame_animation_list)获得AnimationDrawable实例
mAnimationDrawable = (AnimationDrawable) getResources().getDrawable(R.drawable.frame_animation_list);
// 将AnimationDrawable实例设置为ImageView的背景
mImageView.setBackground(mAnimationDrawable);
}
/**
* 2.2 通过xml添加帧动画-方法2
*/
private void initAnimationDrawable3() {
// 将动画资源设置为ImageView的背景资源
mImageView.setBackgroundResource(R.drawable.frame_animation_list);
// 通过get ImageView背景获得AnimationDrawable实例
mAnimationDrawable = (AnimationDrawable) mImageView.getBackground();
}
啥也不说了,上图!
帧动画还是比较简单的,主要用于多幅图片的逐帧播放,感觉应用场景不是很多。