ValueAnimator、ObjectAnimator 除了 ofInt()、ofFloat()、ofObject() 函数创建 Animator 实例的方法以外,都还有一个方法:
4.1.1 PropertyValuesHolder
1. 概述
PropertyValuesHolder 这个类的意义就是,它其中保存了动画过程中所需要操作的属性和对应的值。我们通过 ofFloat(Object target, String propertyName, float… values) 构造的动画,ofFloat() 的内部实现其实就是将传进来的参数封装成 PropertyValuesHolder 实例来保存动画状态。在封装成 PropertyValuesHolder 实例以后,后期的各种操作也是以 PropertyValuesHolder 为主的。
PropertyValuesHolder 中有很多函数,有些函数的 api 等级是11,有些函数的 api 等级是 14 和 21,具体参考文档《Google:PropertyValuesHolder》
首先,我们来看看创建实例的函数:
2. PropertyValuesHolder 之 ofFloat()、ofInt()
1)ofFloat()、ofInt()
- propertyName:表示 ObjectAnimator 需要操作的属性名。即 ObjectAnimator 需要通过反射查找对应属性的 setProperty() 函数的那个 property。
- values:属性所对应的参数,同样是可变长参数,可以指定多个,还记得我们在 ObjectAnimator 中讲过,如果只指定了一个,那么 ObjectAnimator 会通过查找 getProperty() 方法来获得初始值。
2)ObjectAnimator.ofPropertyValuesHolder()
ObjectAnimator 提供了一个方法,构造 PropertyValuesHolder 来构造动画。
- target:指需要执行动画的控件。
- values:是一个可变长参数,可以传进去多个PropertyValuesHolder 实例,由于每个 PropertyValuesHolder 实例都会针对一个属性做动画,所以如果传进去多个 PropertyValuesHolder 实例,将会对控件的多个属性同时做动画操作。
3)示例
|
|
3. PropertyValuesHolder 之 ofObject()
1)概述
- propertyName:ObjectAnimator 动画操作的属性名。
- evaluator:Evaluator 实例,Evaluator 是将当前动画进度计算出当前值的类,可以使用系统自带的 IntEvaluator、FloatEvaluator 也可以自定义。
- values:可变长参数,表示操作动画属性的值。
2)示例:
|
|
自定义 View 和 Evaluator
4.1.2 Keyframe
1. 概述
如果要控制动画速率的变化,可以通过自定义插值器,也可以通过自定义 Evaluator 来实现。但需要足够的数学知识。 为了解决方便的控制动画速率的问题,谷歌为了我们定义了一个 KeyFrame 的类,KeyFrame 直译过来就是关键帧。
- fraction:表示当前的显示进度,即从加速器中 getInterpolation() 函数的返回值。
- value:表示当前应该在的位置。
比如 Keyframe.ofFloat(0, 0) 表示动画进度为 0 时,动画所在的数值位置为 0;Keyframe.ofFloat(0.25f, -20f) 表示动画进度为 25% 时,动画所在的数值位置为 -20;Keyframe.ofFloat(1f, 0) 表示动画结束时,动画所在的数值位置为 0。
PropertyValuesHolder 是这样使用 KeyFrame 对象的:
- propertyName:动画所要操作的属性名。
- values:Keyframe 的列表,PropertyValuesHolder 会根据每个 Keyframe 的设定,定时将指定的值输出给动画。
所以完整的 KeyFrame 的使用代码应该是这样的:
2. 示例
1)布局文件 act_main.xml
2)MainActivity.java 核心代码
3. ofInt 和 ofFloat
|
|
fraction 表示当前关键帧所在的动画进度位置,value 表示当前位置所对应的值。
Keyframe 还有一些常用函数来设置 fraction,value 和 interpolator,定义如下:
如果使用 ofFloat(float fraction) 来构造,也必须使用 setValue(Object value) 来设置这个关键帧所对应的值。
4. 插值器
如果给某个 Keyframe 设置上插值器,那么这个插值器就是从上一个 Keyframe 开始到当前设置插值器的 Keyframe 时,这个过程值的计算是利用这个插值器的,比如:
在上面的代码中,我们给 frame1 设置了插值器 BounceInterpolator,那么在 frame0 到 frame1 的中间值计算过程中,就是用的就是回弹插值器;同样,我们给 frame2 设置了线性插值器 LinearInterpolator,所以在 frame1 到 frame2 的中间值计算过程中,使用的就是线性插值器。很显然,给 Keyframe.ofFloat(0f, 0) 设置插值器是无效的,因为它是第一帧。
5. Keyframe 之 ofObject
|
|
同样,如果使用 ofObject(float fraction) 来构造,也必须使用 setValue(Object value) 来设置这个关键帧所对应的值。
还以 TextView 更改字母的例子来使用下 Keyframe.ofObject:
6. 疑问:如果没有设置进度为0或者进度为1时的关键帧,展示是怎样的?
- 如果去掉第 0 帧,将以第一个关键帧为起始位置。
- 如果去掉结束帧,将以最后一个关键帧为结束位置。
- 使用 Keyframe 来构建动画,至少要有两个或两个以上帧,否则崩溃。
4.1.3 PropertyValuesHolder 其他函数
PropertyValuesHolder 除了上面的讲到的 ofInt、ofFloat、ofObject、ofKeyframe 以外,API 11 的还有几个函数:
4.1.4 示例:电话响铃效果
核心代码