补间动画详解一 基类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 ......
}

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

linux中内核延时函数

第一类延时函数原型是:(忙等) void ndelay(unsigned long nsecs); void udelay(unsigned long usecs); void mdelay(u...

Android 动画之三 Property Animation—— 属性(Property)动画 【Animator提供基类】

参考大神介绍:http://blog.csdn.net/lmj623565791/article/details/38067475 前面我们介绍了补间动画,而今天我们介绍的属性动画可以说是增强版的补...

Android 补间动画Animation的实用应用

转载请注明: http://blog.csdn.net/sinat_30276961/article/details/49868409上一篇,我总结了补间动画的各种特性,并写了个小的应用来使用这些特...

Android中补间动画1----Animation的基本使用代码实现(平移,缩放,渐变,旋转)

效果图: MainActivity package com.zhh.android; import android.app.Activity; import android.cont...

Android中补间动画4----Animation的插值器Interpolator的使用

效果图 Main4Activity package com.zhh.android; import android.support.v7.app.AppCompatActivity;...

Android Animation之补间动画

Android Animation之补间动画转载请注明: http://blog.csdn.net/sinat_30276961/article/details/49721207 最近工作忙,导...

Android补间动画(Tween Animation)的使用总结

前言: 1> 补间动画有四种:平移/缩放/透明度/旋转,这四点将会通过代码示例一来进行说明; 2> 关于补间动画的实质,并不是控件的移动,只是控件的重绘,控件实质是没有进行移动的,这点则通过代码二来进...

补间动画实例(Animation)

Android补间动画简单实例

Tween Animation 补间动画 xml中的简单实现

首先 Tween Animation 一共有四种,分别为

android 补间动画 tween animation xml基本属性

Tween动画是展现出旋转、渐变、移动、缩放的这么一种转换过程,即补间动画。Tween动画有两种定义方式:XML形式,编码形式。 XML定义动画,按照动画定义语法完成XML,置于/res/ani...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:补间动画详解一 基类Animation
举报原因:
原因补充:

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