逐帧动画详解

原创 2016年08月30日 20:36:45
概述
逐帧动画(Frame Animation),是通过将一系列图片按照一定的顺序展示实现的动画。同是视图动画(View Animation),在使用时比补间动画(Tween animation)要简单很多。

一、逐帧动画的使用
(1).使用xml文件创建
节点介绍:
<animation-list>:必须作为根元素,可以包含一个或多个<item>元素。
<item>:代表一帧动画。
属性介绍:
android:oneshot:若等于true,动画只执行一次;否则一直循环。
android:drawable:当前帧所对应的图片资源。
android:duration:当前帧持续的时长,单位毫秒。

示例代码:
/res/drawable目录下添加如下5张图片。

在/res/drawable目录下添加wifi_anim.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/card_icon_wifi_0" android:duration="500" />
    <item android:drawable="@drawable/card_icon_wifi_1" android:duration="500" />
    <item android:drawable="@drawable/card_icon_wifi_2" android:duration="500" />
    <item android:drawable="@drawable/card_icon_wifi_3" android:duration="500" />
    <item android:drawable="@drawable/card_icon_wifi_4" android:duration="500" />
</animation-list>
将上面创建的动画应用到布局的View中。
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/wifi_anim"/>
在java代码中启动动画。
// 获取AnimationDrawable对象
AnimationDrawable animation = (AnimationDrawable) imageView.getBackground();
// 启动动画
animation.start();

(2).使用java代码创建
示例代码:
AnimationDrawable animation = new AnimationDrawable();
for (int i = 0; i < 5; i++) {
  int id = getResources().getIdentifier("card_icon_wifi_" + i, "drawable", getPackageName());
  Drawable drawable = getResources().getDrawable(id);
  // 调用addFrame()方法依次添加drawable对象
  animation.addFrame(drawable, 500);
}
// 添加到View中
imageView.setBackgroundDrawable(anim);
// 启动动画
animation.start();

注意:在Activity的onCreate()方法中,由于Window对象还未初始化完成,此时调用animation.start(),动画不会执行。若需要在Activity启动时就显示动画,可以在onWindowFocusChanged(boolean hasFocus)方法中启动。

二、逐帧动画的分析
逐帧动画是通过AnimationDrawable类来实现。在AnimationDrawable类中,定义了一个AnimationState类型的成员变量mAnimationState,用来存储一系列的drawable对象。
public class AnimationDrawable extends DrawableContainer implements Runnable, Animatable {
    // ...
    private AnimationState mAnimationState;
    // ...
}

AnimationState继承自DrawableContainerState类。AnimationState类自己定义了成员变量mDurations和mOneShot,分别存储每一帧的时长和动画是否需要循环。而在其父类中有一个Drawable类型数组mDrawables,用于存储每一帧drawable对象。
private final static class AnimationState extends DrawableContainerState {
    // ...
    private int[] mDurations;
    private boolean mOneShot = false;
    // ...

    public void addFrame(Drawable dr, int dur) {
        // ...
        int pos = super.addChild(dr);
        mDurations[pos] = dur;
	// ...
    }
    // ...
}

public abstract static class DrawableContainerState extends ConstantState {
    // ...
    Drawable[] mDrawables;
    // ...

    public final int addChild(Drawable dr) {
        // ...
        mDrawables[pos] = dr;
	// ...
    }
}

当调用addFrame()方法时,动画的每一帧被依次添加到成员变量mAnimationState中。
public void addFrame(@NonNull Drawable frame, int duration) {
    mAnimationState.addFrame(frame, duration);
    if (!mRunning) {
        setFrame(0, true, false);
    }
}

最后,调用start()方法启动动画。方法内部调用了setFrame()方法,在setFrame()中调用selectDrawable(),传入当前帧的索引,并在方法最后调用invalidateSelf()重写绘制。
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) {
    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]);
    }
}

版权声明:本文为博主原创文章,转载请注明出处。

相关文章推荐

定时开关机

写一个定时关机的小程序,可以立即关闭计算机,也可以一段时间后关闭计算机。 这里主要考察system()命令。 代码实现: #include#include#includeint ...

banner

banner 命令将 ASCII 字符 String 以大型字母的形式写至标准输出。输出中的每行最长可达 10 大写或小写字符。输出时,所有字符显示为大写,其中小写输入字符看起来比大写输入字符稍小。 ...
  • ace_fei
  • ace_fei
  • 2011年10月14日 10:35
  • 471

android之逐帧,补间动画详解。

在android的世界中有三种动画,它们就是逐帧动画,补间动画,属性 动画。接下来我就分别演示下三种动画的简单用法。各动画的定义: 逐帧动画:就是短时间切换图片,让人们肉眼看起来是连续的,其实就是播放...

Android动画详解(一) 逐帧动画

1、 逐帧动画说明从字面上理解就是一帧挨着一帧的播放多张图片,就像放电影一样。2、实现方式2.1 xml drawable资源配置2.1.1 将准备好的多张图片放入res/drawable目录下2.1...

Android中的动画实现详解(2)--逐帧动画

下面就开始各动画方式的介绍,首先介绍的是逐帧动画。        逐帧动画是Android中最简单的动画,主要你拥有动画的所有的静态图片,那么你就可以实现该动画。虽然该动画实现简单,但是却反映了动画...

Android动画之逐帧动画(Frame Animation)实例详解

本文实例分析了Android动画之逐帧动画。分享给大家供大家参考,具体如下: 在开始实例讲解之前,先引用官方文档中的一段话: Frame动画是一系列图片按照一定的顺序展示的过程,和放电影的...

Android 动画系列之逐帧(Frame)动画详解

前段时间太忙了,已经好久没发博客了,好多想写的东西都没时间写,想了想,这个星期就抽时间写一个动画合集吧,把Android中用到的动画做一个大合集。忘记的时候可以上博客来看看。这一篇就先写Android...
  • Airsaid
  • Airsaid
  • 2016年06月01日 22:47
  • 1176

Android动画之逐帧动画(FrameAnimation)详解

转载请注明出处:http://blog.csdn.net/xiaohao0724/article/details/54582965 Android中的动画,大概分为三种: 1、逐帧动画...

安卓动画之逐帧动画Frame-by-frame Animations详解

一、逐帧动画实现 1. Frame动画是一系列图片按照一定的顺序展示的过程,和放电影的机制很相似,我们称为逐帧动画。Frame动画可以被定义在XML文件中,也可以完全编码实现(Frame-by...

逐帧动画讲解

  • 2017年12月01日 10:16
  • 203KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:逐帧动画详解
举报原因:
原因补充:

(最多只允许输入30个字)