概述
简介
- 实现属性动画中的一个核心方法类
- 继承自ValueAnimator类,即底层的动画实现机制是基于ValueAnimator类
原理
直接对对象的属性值进行改变操作,从而实现动画效果。如直接改变 View的 alpha 属性 从而实现透明度的动画效果。
通过不断控制 值 的变化,再不断 自动 赋给对象的属性,从而实现动画效果。如下图:

基础使用
因为是继承了ValueAnimator类,所以使用的方法和前面学的十分类似:XML 设置 / Java设置
Java代码设置
1 | ObjectAnimator animator = ObjectAnimator.ofFloat(Object object, String property, float ....values); |
上述代码中,如果输入了不存在的 property 属性,Androidstudio会提示的
基本属性
1 | //1、透明度:alpha |

各种属性的详细解释和演示:
https://wiki.jikexueyuan.com/project/android-animation/7.html
XML 代码中设置
res/animator/set_animation.xml
1 | // ObjectAnimator 采用<animator> 标签 |
在Java代码中启动动画
1 | Animator animator = AnimatorInflater.loadAnimator(context, R.animator.set_animation); |
使用实例
1 | public class Demo_ObjectAnimator extends AppCompatActivity { |
效果:

通过自定义对象属性实现动画效果
说明
- 在上面的学习中,我们使用了属性动画最基本的四种动画效果:透明度、平移、旋转 & 缩放
即在
ObjectAnimator.ofFloat()的第二个参数String property传入alpha、rotation、translationX和scaleY等
其实,
ofFloat()的第二个参数可以传入 任意属性值。ObjectAnimator类 对 对象属性值 进行改变从而实现动画效果的本质是:通过不断控制 值 的变化,再不断 自动 赋给对象的属性,从而实现动画效果。而 自动赋给对象的属性 的本质是调用该对象属性的 set() & get() 方法进行赋值
所以,
ObjectAnimator.ofFloat(Object object, String property, float ....values)的第二个参数传入值的作用是:让ObjectAnimator类根据传入的属性名 去寻找 该对象对应属性名的set() & get()方法,从而进行对象属性值的赋值,如上面的例子:1
2
3
4
5
6
7
8
9
10
11
12
13ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, "rotation", 0f, 360f);
// 其实Button对象中并没有rotation这个属性值
// ObjectAnimator并不是直接对我们传入的属性名进行操作
// 而是根据传入的属性值"rotation" 去寻找对象对应属性名对应的get和set方法,从而通过set() & get()对属性进行赋值
// 因为Button对象中有rotation属性所对应的get & set方法
// 所以传入的rotation属性是有效的
// 所以才能对rotation这个属性进行操作赋值
public void setRotation(float value);
public float getRotation();
// 实际上,这两个方法是由View对象提供的,所以任何继承自View的对象都具备这个属性
原理解析
1 | // 使用方法 |
自动赋值的逻辑:
- 初始化时,如果属性的初始值没有提供,则调用属性的
get()进行取值; - 当 值 变化时,用对象该属性的
set()方法,从而从而将新的属性值设置给对象属性。
所以:
ObjectAnimator类针对的是任意对象 & 任意属性值,并不是单单针对于View对象- 如果需要采用
ObjectAnimator类实现动画效果,那么需要操作的对象就必须有该属性的set() & get()
具体使用
对于属性动画,其拓展性在于:不局限于系统限定的动画,可以自定义动画,即自定义对象的属性,并通过操作自定义的属性从而实现动画。
那么,该如何自定义属性呢?本质上,就是:
- 为对象设置需要操作属性的
set() & get()方法 - 通过实现TypeEvaluator类从而定义属性变化的逻辑
- 类似于ValueAnimator的过程
实例练习
实现的动画效果:一个圆的颜色渐变
逻辑如下:

步骤1:设置对象类属性的 set() & get() 方法
通过继承原始类,直接给类加上该属性的
get()&set(),从而实现给对象加上该属性的get()&set()通过包装原始动画对象,间接给对象加上该属性的
get()&
set()。即 用一个类来包装原始对象
下面用第一种来实现一下:
MyView2.java
1 | public class MyView2 extends View { |
步骤2:在布局中引入myview2
1 |
|
步骤3:根据需求实现TypeEvaluator接口
1 | public class ColorEvaluator implements TypeEvaluator { |
步骤4: 调用ObjectAnimator.ofObject() 方法
自定义对象属性,我们用的是 ObjectAnimator.ofObject() 方法,该方法不同于前面的ofFloat(),需要额外传入一个自定义的属性估值器
源码:
1 | public static ObjectAnimator ofObject(Object target, String propertyName, |
方法调用:
1 | public class Demo_ObjectAnimator2 extends AppCompatActivity { |
效果

说明
ObjectAnimator类 自动赋给对象的属性 的本质是调用该对象属性的set() & get()方法进行赋值所以,
ObjectAnimator.ofFloat(Object object, String property, float ....values)的第二个参数传入值的作用是:让ObjectAnimator类根据传入的属性名 去寻找 该对象对应属性名的set() & get()方法,从而进行对象属性值的赋值从上面的原理可知,如果想让对象的属性a的动画生效,属性a需要同时满足下面两个条件:
- 1.对象必须要提供属性a的set()方法
a. 如果没传递初始值,那么需要提供 get() 方法,因为系统要去拿属性a的初始值
b. 若该条件不满足,程序直接Crash- 对象提供的 属性a 的
set()方法 对 属性a的改变 必须通过某种方法反映出来
a. 如带来ui上的变化
b. 若这条不满足,动画无效,但不会Crash
上述条件,一般第二条都会满足,主要是在第一条
- 比如说:由于
View的setWidth()并不是设置View的宽度,而是设置View的最大宽度和最小宽度的;所以通过setWidth()无法改变控件的宽度;所以对View视图的width做属性动画没有效果- 具体请看下面Button按钮的例子
1 | Button mButton = (Button) findViewById(R.id.Button); |

运行后,会看到其宽度并不会变化
为什么没有动画效果呢?我们来看View 的 setWidth方法
1 | public void setWidth(int pixels) { |
上述问题解决方案
针对上述对象属性的set()不是设置属性 或 根本没有set() / get()的情况应该如何处理?
手动设置对象类属性的set() & get()。共有两种方法:
- 通过继承原始类,直接给类加上该属性的
get()&set(),从而实现给对象加上该属性的get()&set() - 通过包装原始动画对象,间接给对象加上该属性的
get()&
set()。即 用一个类来包装原始对象
对于第一种方法,在上面的例子已经说明;下面主要学第二种方法:通过包装原始动画对象,间接给对象加上该属性的get()& set()
还是采用上述 Button 按钮的例子
1 | public class MainActivity extends AppCompatActivity { |
发现这次就得到了我们想要的效果

Demo 地址
https://github.com/Commandercc/DemoEX/blob/master/AnimationDmeo3.zip