Android动画系列|Android动画篇(五)—— 属性动画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动画系列|Android动画篇(五)—— 属性动画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动画系列|Android动画篇(五)—— 属性动画ObjectAnimator基本使用
文章图片

从图中可以看到(画的有点丑)X轴和Y轴中黑色区域是手机屏幕,Z轴表示从屏幕左上角向正前方延伸的一条轴。
(1)setRotation
//围绕Z轴旋转,这里从0度旋转360度后再旋转到0度 ObjectAnimatoranimator = 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度 ObjectAnimatoranimator = 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度 ObjectAnimatoranimator = 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动画系列|Android动画篇(五)—— 属性动画ObjectAnimator基本使用
文章图片
Android动画系列|Android动画篇(五)—— 属性动画ObjectAnimator基本使用
文章图片
Android动画系列|Android动画篇(五)—— 属性动画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动画系列|Android动画篇(五)—— 属性动画ObjectAnimator基本使用
文章图片
Android动画系列|Android动画篇(五)—— 属性动画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动画系列|Android动画篇(五)—— 属性动画ObjectAnimator基本使用
文章图片
Android动画系列|Android动画篇(五)—— 属性动画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动画系列|Android动画篇(五)—— 属性动画ObjectAnimator基本使用
文章图片

从图中可以看到,颜色在三个值之间平缓地向另一个颜色变化。
二、ObjectAnimator动画原理 ValueAnimator和ObjetAnimator的动画流程大致相同,也是通过加速器返回当前进度,并且通过计算器Evaluator计算进度所对应的数字值,唯一不同的是最后一步,在valueAnimator中我们需要添加监听器来监听当前值;而ObjectAnimator是根据属性值拼接成相应的set属性函数,如下图的alpha的拼接方法就是将属性的第一个字母强制大写后,与set拼接,变成setAlpha,然后通过反射找到控件的setAlpha(float alpha)函数,并且将当前值作为setAlpha(float alpha)参数传入。找到控件的set函数后,通过反射来调用该函数。
Android动画系列|Android动画篇(五)—— 属性动画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的使用
【Android动画系列|Android动画篇(五)—— 属性动画ObjectAnimator基本使用】以上几篇动画文章是一定要掌握的,写的不好请多多指出!

    推荐阅读