接上一篇文章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();
- }
-
啥也不说了,上图!
帧动画还是比较简单的,主要用于多幅图片的逐帧播放,感觉应用场景不是很多。