补间动画详解一 基类Animation

原创 2016年08月28日 19:19:27

补间动画(Tween animation)是通过在两个关键帧之间补充渐变的动画效果来实现的。

Android系统提供了四个补间动画的类,分别是AlphaAnimationRotateAnimationScaleAnimationTranslateAnimation,另外还有一个能够把多个动画组合起来的AnimationSet类,这些类都有一个共同的基类Animation。

Animation类官方文档:
https://developer.android.com/reference/android/view/animation/Animation.html

类图:


一、Animation介绍

Animation是一个抽象类,无法直接使用,通常使用的是它的直接子类。

public abstract class Animation implements Cloneable {
}

Animation类定义了一些与动画相关的变量,子类可以直接使用。
/**
 * 一个动画周期的持续时间,以毫秒为单位。
 */
long mDuration;

/**
 * 动画开始执行的延时时长。如果大于0,动画的执行时间为startTime+startOffset。
 */
long mStartOffset;

/**
 * 设置为true时,将保持动画开始前的状态。默认值为true。
 */
boolean mFillBefore = true;

/**
 * 设置为true时,将保持动画结束时的状态。默认值为false。
 */
boolean mFillAfter = false;

/**
 * 设置为true时,将应用mFillBefore的值;否则,忽视mFillBefore的值。默认值为false。
 */
boolean mFillEnabled = false;

/**
 * 动画重复的次数。
 */
int mRepeatCount = 0;

/**
 * 动画的重复类型,取值为RESTART(从头播放)或REVERSE(倒序回放)。
 */
int mRepeatMode = RESTART;

/**
 * 表示动画在执行期间,被设置动画的内容在Z轴上的顺序。
 * 取值范围ZORDER_NORMAL(保持不动)、ZORDER_TOP(在所有其他内容的顶部)、ZORDER_BOTTOM(在所有其他内容的底部),默认为ZORDER_NORMAL
 */
private int mZAdjustment;

/**
 * 动画的背景色。
 */
private int mBackgroundColor;

/**
 * 如果设置为true,并且动画窗体有一个壁纸的话,那么动画只会应用给窗体,壁纸是静止不动的。默认值为false。
 */
private boolean mDetachWallpaper = false;

/**
 * 插值器,用来修饰动画效果。
 */
Interpolator mInterpolator;

同时也有一些常量,用来给特定的变量赋值。
/**
 * mRepeatCount设置为INFINITE,表示动画无限循环。
 */
public static final int INFINITE = -1;

/**
 * mRepeatMode设置为RESTART,表示动画结束后从头开始执行。
 */
public static final int RESTART = 1;

/**
 * mRepeatMode设置为REVERSE,表示动画结束后反过来执行。
 */
public static final int REVERSE = 2;

/**
 * setStartTime()传入该值时,动画将在第一次调用getTransformation(long, Transformation)时开始执行。
 */
public static final int START_ON_FIRST_FRAME = -1;

/**
 * 具体的坐标值。
 */
public static final int ABSOLUTE = 0;

/**
 * 相对自身的坐标值。
 */
public static final int RELATIVE_TO_SELF = 1;

/**
 * 相对父容器的坐标值。
 */
public static final int RELATIVE_TO_PARENT = 2;

/**
 * mZAdjustment设置为ZORDER_NORMAL,表示内容在Z轴保持不动。
 */
public static final int ZORDER_NORMAL = 0;

/**
 * mZAdjustment设置为ZORDER_TOP,表示内容的Z轴方向在所有其他内容的顶部。
 */
public static final int ZORDER_TOP = 1;

/**
 * mZAdjustment设置为ZORDER_BOTTOM,表示内容的Z轴方向在所有其他内容的底部。
 */
public static final int ZORDER_BOTTOM = -1;

这些成员变量在构造方法中被初始化。
public Animation(Context context, AttributeSet attrs) {
    TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Animation);

    setDuration((long) a.getInt(com.android.internal.R.styleable.Animation_duration, 0));
    setStartOffset((long) a.getInt(com.android.internal.R.styleable.Animation_startOffset, 0));

    setFillEnabled(a.getBoolean(com.android.internal.R.styleable.Animation_fillEnabled, mFillEnabled));
    setFillBefore(a.getBoolean(com.android.internal.R.styleable.Animation_fillBefore, mFillBefore));
    setFillAfter(a.getBoolean(com.android.internal.R.styleable.Animation_fillAfter, mFillAfter));

    setRepeatCount(a.getInt(com.android.internal.R.styleable.Animation_repeatCount, mRepeatCount));
    setRepeatMode(a.getInt(com.android.internal.R.styleable.Animation_repeatMode, RESTART));

    setZAdjustment(a.getInt(com.android.internal.R.styleable.Animation_zAdjustment, ZORDER_NORMAL));

    setBackgroundColor(a.getInt(com.android.internal.R.styleable.Animation_background, 0));

    setDetachWallpaper(a.getBoolean(com.android.internal.R.styleable.Animation_detachWallpaper, false));

    final int resID = a.getResourceId(com.android.internal.R.styleable.Animation_interpolator, 0);

    a.recycle();

    if (resID > 0) {
        setInterpolator(context, resID);
    }

    ensureInterpolator();
}
上面的每一个成员变量都有与之对应的set方法和xml属性。以成员变量mDuration为例,它的set方法为setDuration(),xml属性为android:duration。

Animation类内部定义了动画的监听器AnimationListener,通过调用setAnimationListener()方法来设置监听器。

AnimationListener mListener;

/**
 * 设置动画的监听
 */
public void setAnimationListener(AnimationListener listener) {
    mListener = listener;
}

/**
 * 动画的监听
 */
public static interface AnimationListener {
    /**
     * 动画开始时回调。
     */
    void onAnimationStart(Animation animation);

    /**
     * 动画结束时回调。
     * 但是当动画重复次数被设置为INFINITE的时候,该方法不会回调。
     */
    void onAnimationEnd(Animation animation);

    /**
     * 动画重复时回调。
     */
    void onAnimationRepeat(Animation animation);
}

Animation类是通过applyTransformation()方法来处理动画变化的过程。
protected void applyTransformation(float interpolatedTime, Transformation t) {
}
可以看到,在Animation类中applyTransformation()方法是空的,具体实现由它的四个子类来完成。每个动画实现类都重载了Animation类的applyTransformation()方法,该方法把一些属性组装成一个Transformation类,该方法会被getTransformation()方法调用。
在动画的执行过程中,会反复的调用applyTransformation()方法。每次调用参数interpolatedTime值都会变化,该参数从0.0递增为1.0,当该参数为1.0时表示动画结束。Transformation类封装了矩阵Matrix和透明度Alpha值,通过参数Transformation来设置Matrix和Alpha,实现各种效果。

如果我们需要实现自己的动画类,需要下面两个步骤:
(1).继承Animation类。
(2).实现applyTransformation()方法。


一、Animation执行过程

在启动动画时,一般是调用View类的startAnimation(anim)方法。
先从View类开始看起。

public void startAnimation(Animation animation) {
    animation.setStartTime(Animation.START_ON_FIRST_FRAME);
    setAnimation(animation);
    invalidateParentCaches();
    invalidate(true);
}

protected Animation mCurrentAnimation = null;

public void setAnimation(Animation animation) {
    mCurrentAnimation = animation;
    // other code ......
}
在startAnimation()方法内部,先调用setAnimation()方法给成员变量mCurrentAnimation赋值,然后它调用invalidate()来重绘自己。

接下来进入draw()方法。
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
    // other code ......
    final Animation a = getAnimation();
    if (a != null) {
        more = applyLegacyAnimation(parent, drawingTime, a, scalingRequired);
    }
    // other code ......
}

public Animation getAnimation() {
    return mCurrentAnimation;
}

private boolean applyLegacyAnimation(ViewGroup parent, long drawingTime,
            Animation a, boolean scalingRequired) {
    // other code ......
    boolean more = a.getTransformation(drawingTime, t, 1f);
    // other code ......
}
在draw()方法内部调用了View类的applyLegacyAnimation(),而applyLegacyAnimation()内部又调用了Animation类的getTransformation(long,Transformation,float)方法。

再次回到Animation类中,会发现最终在getTransformation()方法中调用了applyTransformation()方法,实现各种动画效果。
public boolean getTransformation(long currentTime, Transformation outTransformation,
    float scale) {
    mScaleFactor = scale;
    return getTransformation(currentTime, outTransformation);
}

public boolean getTransformation(long currentTime, Transformation outTransformation) {
    // other code ......
    applyTransformation(interpolatedTime, outTransformation);
    // other code ......
}

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/ruancoder/article/details/52347243

Animation 动画介绍和实现

Android 平台提供了两类动画。 第一类就是 Frame动画(AnimationDrawable),帧动画。 由一张张的图片连续显示呈现出来的动画。 在drawable目录下创建一个配置文件。标签...
  • ideal_Utopia
  • ideal_Utopia
  • 2016-07-09 00:40:45
  • 998

Android 属性动画(Property Animation) 完全解析 (上)

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/380674751、概述Android提供了几种动画类型:View Animatio...
  • lmj623565791
  • lmj623565791
  • 2014-07-25 09:34:10
  • 329525

Android动画总结系列(3)——补间动画源码分析

本文分析了补间动画的源码,总结了补间动画的实现思路,总体来讲,补间动画就是外部调用方(View)不断的传入真实执行时间,动画根据真实时间计算插值时间,再根据插值时间计算当前位置的转化效果,并应用在外部...
  • u013478336
  • u013478336
  • 2016-08-14 23:38:31
  • 1416

HTML5新的东西:Canvas里面KineticJS补间动画教程!

与KineticJS到二层属性,我们可以实例化一个动力。二层对象,然后启动二层通过调用玩()。任何数值属性的一个形状、组层,或阶段可以转为,如 x, y, rotation, width, heigh...
  • u012526912
  • u012526912
  • 2013-10-21 21:17:46
  • 901

canvas动画函数requestAnimationFrame

canvas原生动画函数requestAnimationFrame
  • qq_22509715
  • qq_22509715
  • 2016-08-26 14:48:38
  • 2481

Animation 动画类型

1.Animation 动画类型 Android的animation由四种类型组成: XML中 alph 渐变透明度动画效果 scale 渐变尺...
  • wu15111685657
  • wu15111685657
  • 2017-07-07 20:17:41
  • 42

Android资源类型之Animation

Android的Resource Types说的是:保存在res/anim,res/drawable,res/color,res/layout,res/menu,res/values目录下的文件所涉及...
  • gongsunjinqian
  • gongsunjinqian
  • 2016-07-13 16:52:42
  • 405

Android Animation动画详解(一): 补间动画

Android的Tween动画由四种类型组成:alpha、scale、translate、rotate。
  • zuiwuyuan
  • zuiwuyuan
  • 2015-08-23 18:50:16
  • 2683

Android开发之Tween(补间动画)完全解析(下)——代码实现

在上一篇文章中,我们详细讨论了Tween动画的xml的实现以及interpolator的使用,相信通过上篇文章大家对Tween动画的xml属性的配置会有一个详细的理解,当然这篇文章也是承接上篇文章,这...
  • dmk877
  • dmk877
  • 2016-07-24 20:30:25
  • 2064

Animation 组件

Animation概述 Animation 组件,Animation类 //测试的结果是: //1、特别注意 XXQueue 这样的函数,如果遇到循环播放的动画 WrapMode.Loop ...
  • douniwan007009
  • douniwan007009
  • 2018-03-25 09:46:56
  • 32
收藏助手
不良信息举报
您举报文章:补间动画详解一 基类Animation
举报原因:
原因补充:

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