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

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

相关文章推荐

安卓的各种动画(透明度,平移,旋转,缩放)以及侦听

透明度动画: 第一种方式: AlphaAnimation aa = new AlphaAnimation(0, 1); aa.setDuration(1000); imageview....

Android动画-旋转、平移、放缩和渐变

转载:http://yidongkaifa.iteye.com/blog/1788996Android 平台提供了两类动画。 一类是Tween动画,就是对场景里的对象不断的进行图像变化来产生动画效果(...

【Android动画】之Frame动画

Android 平台提供了两类动画。 一类是Tween动画,就是对场景里的对象不断的进行图像变化来产生动画效果(旋转、平移、放缩和渐变)。第二类就是 Frame动画,即顺序的播放事先做好的图像,与gi...

补间动画详解四 平移动画TranslateAnimation

TranslateAnimation是平移动画的类,负责View的位移。 TranslateAnimation类官方文档: https://developer.android.com/refe...

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

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/380674751、概述Android提供了几种动画类型:View Animatio...

Android 7.0 行为变更 通过FileProvider在应用间共享文件吧

本文已在我的公众号hongyangAndroid原创首发。 转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/7285...

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

上一篇Android 属性动画(Property Animation) 完全解析 (上)已经基本展示了属性动画的核心用法:ObjectAnimator实现动画,ValueAnimator实现动画,An...

TranslateAnimation从上往下平移动画

TranslateAnimation从上往下平移动画

【Android动画】之Tween动画 (渐变、缩放、位移、旋转)

Android 平台提供了两类动画。 一类是Tween动画,就是对场景里的对象不断的进行图像变化来产生动画效果(旋转、平移、放缩和渐变)。第二类就是 Frame动画,即顺序的播放事先做好的图像,与gi...

Android Acitivy切换平移动画效果实现

以切换到下一页效果实现为例: 1.在anim目录下新建anim文件夹,新建tran_in.xml和tran_out.xml分别表示下一页切换进入,和本页切换出去。 即in表示下一页向左平移,out...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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