天天看点

Android动画篇(五)—— 属性动画ObjectAnimator基本使用一、概述二、使用二、ObjectAnimator动画原理

前言:宝剑锋从磨砺出,梅花香自苦寒来。

一、概述

       上几篇给大家讲解了ValueAnimator的相关用法,但是ValueAnimator有个缺点,只能对数值对动画计算,我需要对那个控件操作就要监听动画过程,在监听中对控件操作,这样使用起来相对于补间动画就麻烦了。

       为了能让动画直接和控件关联,使我们从监听动画中解放出来,在ValueAnimator的基础上又派生了一个类:ObjectAnimator,由于ObjectAnimator是派生自ValueAnimator,所以ValueAnimator能使用的方法在ObjectAnimator中都能正常使用。

1、基础属性

(1)常用函数

/**
 * 设置动画时长,单位是毫秒
 */
ValueAnimator setDuration(long duration)
/**
 * 获取ValueAnimator在运动时,当前运动点的值
 */
Object getAnimatedValue();
/**
 * 开始动画
 */
void start()
/**
 * 设置循环次数,设置为INFINITE表示无限循环
 */
void setRepeatCount(int value)
/**
 * 设置循环模式
 * value取值有RESTART,REVERSE,
 */
void setRepeatMode(int value)
/**
 * 取消动画
 */
void cancel()
           

(2)监听器

/**
 * 监听器一:监听动画变化时的实时值
 */
public static interface AnimatorUpdateListener {
    void onAnimationUpdate(ValueAnimator animation);
}
//添加方法为:public void addUpdateListener(AnimatorUpdateListener listener)
 
/**
 * 监听器二:监听动画变化时四个状态
 */
public static interface AnimatorListener {
    void onAnimationStart(Animator animation);
    void onAnimationEnd(Animator animation);
    void onAnimationCancel(Animator animation);
    void onAnimationRepeat(Animator animation);
}
//添加方法为:public void addListener(AnimatorListener listener) 
 
/**
 *监听器三:监听动画暂停和暂停后再恢复的状态
 */
    public static interface AnimatorPauseListener {
        void onAnimationPause(Animator animation);
        void onAnimationResume(Animator animation);
    }
//添加方法:public void addPauseListener(AnimatorPauseListener listener)
           

(3)插值器与Evaluator

/**
 * 设置插值器
 */
public void setInterpolator(TimeInterpolator value)
/**
 * 设置Evaluator
 */
public void setEvaluator(TypeEvaluator value)
           

部分常用函数已经在这里贴出来,使用方法可以参考《 Android动画篇(三)—— 属性动画ValueAnimator的使用》,有关插值器和Evaluator的部分可以参考《ValueAnimator的高级进阶》。

二、使用

ObjectAnimator也重写了几个方法,如ofInt()、ofFloat()等,我们先看看ObjectAnimator重写的ofFloat()如何实现动画效果:

1、alpha

  • setAlpha(float alpha)          设置透明度,alpha表示透明度值;0表示完全透明,1表示完全不透明
ObjectAnimator animator = ObjectAnimator.ofFloat(mTextView, "alpha", 1f, 0f, 1f);
animator.setDuration(2000);
animator.start();
           

效果图如下:

Android动画篇(五)—— 属性动画ObjectAnimator基本使用一、概述二、使用二、ObjectAnimator动画原理

上面的代码中将TextView的透明度从1变为0再变为1,我们来看一下构造函数:

public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)

 public static ObjectAnimator ofInt(Object target, String propertyName, float... values)
 public static ObjectAnimator ofArgb(Object target, String propertyName, float... values)
           
  • Object target                  目标控件,需要操作该动画的控件
  • String propertyName     操作这个控件的哪一个动画属性
  • float... values                  可变长参数,这个就和ValueAnimator中的可以长参数意义一样,指定的值从哪变到哪,表示动画                                            的变化范围,比如上面的透明度,从1变为0再变为1。

ofFloat()与ofInt()和ofArgb()主要是参数的类型不一样,其他参数的意义是一样的,这里就不多描述。在上面的透明度动画中可以知道,设置了propertyName参数后就能实现具体的动画。我们是怎么知道这里需要的是什么值呢?

2、set函数

我们重新来看一下alpha的ObjectAnimator方法:

ObjectAnimator animator = ObjectAnimator.ofFloat(mTextView, "alpha", 1f, 0f, 1f);
           

试问TextView有alpha这个属性吗?没有,连它的父控件View也没有这个属性。那么这个参数是怎么和控件的动画关联起来的呢?其实ObjectAnimator并不是根据控件的XML属性来改变的,而是通过指定属性所对应的set方法来改变的。比如上面我们使用alpha指定的属性值,ObjectAnimator在做动画时就会到指定控件(TextView)中找到对应setAlpha()来改变控件属性的值。我们看一下常用的几种方法:

//1、透明度:alpha
public void setAlpha(float alpha)
 
//2、旋转度数:rotation、rotationX、rotationY
public void setRotation(float rotation)
public void setRotationX(float rotationX)
public void setRotationY(float rotationY)

//3、缩放:scaleX、scaleY
public void setScaleX(float scaleX)
public void setScaleY(float scaleY)

//4、平移:translationX、translationY
public void setTranslationX(float translationX) 
public void setTranslationY(float translationY)
 
           

可以看到在view中已经实现了alpha,rotation,scale,translation的相关set方法,我们在构造ObjectAnimator的时候可以直接使用。

总结:

(1)要使用ObjectAnimator来构造动画,要操作的控件中,必须存在该控件对应属性的set方法                                     

(2)set方法的命名必须以骆驼的命名方法来规定,即set后面的每个单词的首个字母大写,其余的小写,比如setAlpha所对应的属性是alpha。

3、rotation

  • setRoation(float rotation)         表示围绕Z轴旋转,rotation表示旋转度数,正数表示正方向,负数表反方向
  • setRoationX(float rotationX)     表示围绕X轴旋转,rotationX表示旋转度数,正数表示正方向,负数表反方向
  • setRoationY(float rotationY)     表示未然Y轴旋转,rotationY表示旋转度数,正数表示正方向,负数表反方向

我们先来看看具体哪个是Z轴,X轴,Y轴:

Android动画篇(五)—— 属性动画ObjectAnimator基本使用一、概述二、使用二、ObjectAnimator动画原理

从图中可以看到(画的有点丑)X轴和Y轴中黑色区域是手机屏幕,Z轴表示从屏幕左上角向正前方延伸的一条轴。

(1)setRotation

//围绕Z轴旋转,这里从0度旋转360度后再旋转到0度
ObjectAnimator  animator = ObjectAnimator.ofFloat(mTextView, "rotation", 0f, 360f, 0f);
animator.setDuration(3000);
animator.start();
           

这里旋转的角度值是(0,360,0),控件从原始位置围绕Z旋转(正方向),从0度转到360度,再转回到0度位置。

(2)setRotationX

//围绕X轴旋转,这里从0度旋转360度后再旋转到0度
ObjectAnimator  animator = ObjectAnimator.ofFloat(mTextView, "rotationX", 0f, 360f, 0f);
animator.setDuration(3000);
animator.start();
           

这里旋转的角度值是(0,360,0),控件从原始位置围绕X旋转(正方向),从0度转到360度,再转回到0度位置。

(3)setRotationY

//围绕Y轴旋转,这里从0度旋转-360度后再旋转到0度
ObjectAnimator  animator = ObjectAnimator.ofFloat(mTextView, "rotationY", 0f, -360f, 0f);
animator.setDuration(3000);
animator.start();
           

这里旋转的角度值是(0,360,0),控件从原始位置围绕Y旋转(反方向),从0度转到-360度,再转回到0度位置。

效果分别如下:

     setRotation(围绕Z轴旋转)                    setRotationX  (围绕X轴旋转)              setRotationY(围绕Y轴旋转)

Android动画篇(五)—— 属性动画ObjectAnimator基本使用一、概述二、使用二、ObjectAnimator动画原理
Android动画篇(五)—— 属性动画ObjectAnimator基本使用一、概述二、使用二、ObjectAnimator动画原理
Android动画篇(五)—— 属性动画ObjectAnimator基本使用一、概述二、使用二、ObjectAnimator动画原理

4、scale

我们来看看setScale的用法:

  • setScaleX(float scaleX)        在X轴上缩放,scaleX表示缩放倍数
  • setScaleY(float scaleY)        在Y轴上缩放,scaleY表示缩放倍数

(1)setScaleX

//围绕X轴缩放,先放大四倍,再变为两倍,再恢复原样
ObjectAnimator animator = ObjectAnimator.ofFloat(mTextView, "scaleX", 0f, 4f, 2f, 1f);
animator.setDuration(3000);
animator.start();
           

(2)setScaleY

这里缩放的倍数是(0,4,2,1),控件在X轴方向上从0放大到4倍,然后变为原来的2倍,最后还原到1倍的初始状态。

//围绕Y轴缩放,先放大四倍,再变为两倍,再恢复原样
ObjectAnimator animator = ObjectAnimator.ofFloat(mTextView, "scaleY", 0f, 4f, 2f, 1f);
animator.setDuration(3000);
animator.start();
           

这里缩放的倍数是(0,4,2,1),控件在Y轴方向上从0放大到4倍,然后变为原来的2倍,最后还原到1倍的初始状态。

效果分别如下:

     setRotationX(围绕X轴缩放)            setRotationY(围绕Y轴缩放)

Android动画篇(五)—— 属性动画ObjectAnimator基本使用一、概述二、使用二、ObjectAnimator动画原理
Android动画篇(五)—— 属性动画ObjectAnimator基本使用一、概述二、使用二、ObjectAnimator动画原理

5、translation

我们来看看translation的用法:

  • setTranslationX(float translationX)    表示在X轴上的移动距离,translationX为移动的距离,正数为正方向,负数为反方                                                                   向,向右为正方向
  • setTranslationY(float translationY)     表示在Y轴上的移动距离,translationY为移动的距离,正数为正方向,负数为反方                                                                   向,向下为正方向

(1)setTranslationX

//在X轴方向上移动,先向右移动400,再向左移动到距离初始位置200,最后回到原点
ObjectAnimator animator = ObjectAnimator.ofFloat(mTextView, "translationX", 0f, 400f, -200f, 0f);
animator.setDuration(3000);
animator.start();
           

这里控件的移动距离是(0,400,-200,0),控件会从初始位置向右移动(正方向)400像素,然后在向左移动(负方向)到距离初始位置的-200像素处,最后回到初始位置。

(2)setTranslationY

//在Y方向上移动,先向下移动400,再向上移动距离初始位置200,最后回到原位置
ObjectAnimator animator = ObjectAnimator.ofFloat(mTextView, "translationY", 0, 400, -200, 0);
animator.setDuration(3000);
//设置循环模式,倒叙回放
animator.setRepeatMode(ValueAnimator.REVERSE);
//循环次数,这里设置了无限循环
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.start();
           

这里的移动距离是(0,400,-200,0),控件会从初始位置向下(正方向)移动400个像素,然后向上(负方向)移动到距离初始位置-200像素处,然后在回到初始位置。这里设置了倒叙回放和无限循环。

效果分别如下:

 setTranslationX(X轴方向移动)         setTranslationY(Y轴方向移动)

Android动画篇(五)—— 属性动画ObjectAnimator基本使用一、概述二、使用二、ObjectAnimator动画原理
Android动画篇(五)—— 属性动画ObjectAnimator基本使用一、概述二、使用二、ObjectAnimator动画原理

从上面可以看出,每次计算的距离都是从中心原点开始计算。

6、BackgroundColor

  • setBackgroundColor(int color)           设置背景颜色,color表示颜色值

这里设置背景颜色需要配合ArgbEvaluator来使用,否则的话控件颜色会跳动,这样能平滑过渡。有关ArgbEvaluator的原理可以参考我的上一篇文章《Android动画篇(四)—— ValueAnimator的高级进阶》

这里ArgbEvaluator的返回值类型是integer,所有我们需要使用ofInt()函数来构造:

ObjectAnimator animator = ObjectAnimator.ofInt(mTextView, "backgroundColor", 0xffff00ff, 0xffffff00, 0xffff00ff);
animator.setDuration(8000);
animator.setEvaluator(new ArgbEvaluator());
animator.start();
           

如下图所示:

Android动画篇(五)—— 属性动画ObjectAnimator基本使用一、概述二、使用二、ObjectAnimator动画原理

从图中可以看到,颜色在三个值之间平缓地向另一个颜色变化。

二、ObjectAnimator动画原理

ValueAnimator和ObjetAnimator的动画流程大致相同,也是通过加速器返回当前进度,并且通过计算器Evaluator计算进度所对应的数字值,唯一不同的是最后一步,在valueAnimator中我们需要添加监听器来监听当前值;而ObjectAnimator是根据属性值拼接成相应的set属性函数,如下图的alpha的拼接方法就是将属性的第一个字母强制大写后,与set拼接,变成setAlpha,然后通过反射找到控件的setAlpha(float alpha)函数,并且将当前值作为setAlpha(float alpha)参数传入。找到控件的set函数后,通过反射来调用该函数。

Android动画篇(五)—— 属性动画ObjectAnimator基本使用一、概述二、使用二、ObjectAnimator动画原理

这里就是ObjectAnimator的流程,最后一步就是调用控件对应属性的set方法,将当前动画数值当参数传进去。

1、注意事项:

(1)拼接set函数的方法:

强制将属性值的第一个字母变成大写,然后与set拼接,就是set函数的名字。注意,我们只是将属性值的第一个字强制大写,后面的保持不变。比如:如果属性函数为setScaleX(float scaleX),那么属性值可以写为"scaleX"或者"ScaleX",第一个字母可以随意大小写,但是后面的必须与属性函数名保持一致。

(2)如何确定函数的参数类型:

参数对应的参数类型是如何决定的呢?在ValueAnimator中,动画中产生的数值的类型与传入参数的类型是一致的,ObjectAnimator也是一样,动画产生的数值类型和传入参数的类型是一致的,但是传入的参数类型与拼接后的函数的参数类型不一致的话会报错,比如我将上图的构造方法改为ofInt(tv, "alpha", 1, 0, 1),系统会利用反射来调用setScaleX(float scaleX),但是并把当前动画数值作为参数传进去,但是这里是Integer类型,实际需要的是Float类型,虽然参数名一样,但是参数类不一样所以会报错。

(3)调用set函数以后:

在ObjectAnimator流程中,动画值参数传给set函数后就结束了,set函数相当于我们在ValueAnimator添加监听的作用,set函数中对控件的操作还是控件自己来做。

至此,本文结束!有关Animator的动画集合和PropertyValuesHolder的用法将在下一篇《Android动画篇(六)—— 组合动画AnimatorSet和PropertyValuesHolder的使用》讲解。

源码下载地址:https://github.com/FollowExcellence/AndroidAnimation

请大家尊重原创者版权,转载请标明出处: https://blog.csdn.net/m0_37796683/article/details/90607428 谢谢!

动画系列文章:

1、 Android动画篇(一)—— alpha、scale、translate、rotate、set的xml属性及用法

  • 补间动画的XML用法以及属性详解
2、Android动画篇(二)—— 代码实现alpha、scale、translate、rotate、set及插值器动画
  • 代码动态实现补间动画以及属性详解
3、 Android动画篇(三)—— 属性动画ValueAnimator的使用
  • ValueAnimator的基本使用
4、 Android动画篇(四)—— 属性动画ValueAnimator的高级进阶
  • 插值器(Interpolator)、计算器(Evaluator)、ValueAnimator的ofObject用法等相关知识
5、 Android动画篇(五)—— 属性动画ObjectAnimator基本使用
  • ObjectAnomator的基本使用以及属性详解
6、 Android动画篇(六)—— 组合动画AnimatorSet和PropertyValuesHolder的使用
  • AnimatorSet动画集合和PropertyValuesHolder的使用
以上几篇动画文章是一定要掌握的,写的不好请多多指出!

继续阅读