- 上次学习了ValueAnimator,但是ValueAnimator只能对动画中的数值进行计算,如果那个控件执行操作,就要实现对该对象的监听,相比于补间动画比较繁琐
- 为了使动画直接与对应的控件相关联,以使我们从监听动画过程中解放出来,Google工程师在ValueAnimator的基础上派生了一个类ObjectAnimator,派生类的特性相信大家都知道。
- 但是ObjectAnimator也重写了几个函数,比如ofInt() ofFloat()等。
//第一个参数指定这个动画要操作的控件
//第二个参数用于指定这个动画要操作控件的哪一个属性
第三个参数是可变长参数,是指这个属性值如何变化
ObjectAnimator animator = ObjectAnimator.ofFloat(textView,"alpha", 1, 0, 1);
animator.setDuration(2000);
animator.start();
- 但是它是如何通过第二个参数实现的控件的动画效果呢:
- 在我们指定控件的动画的时候,ObjectAnimator会在TextView中去找对应的set函数,这些函数都是从View中继承来的,在View中有关动画的函数如下:
函数作用 | 方法 |
---|---|
设置透明度 | public void setAlpha(float alpha) |
设置绕Z轴旋转度数 | public void setRotation(float rotation) |
设置绕X轴旋转度数 | public void setRotationX(float rotationX) |
设置绕Y轴旋转度数 | public void setRotationY(float rotationY) |
在X轴上平移(控件为原点向右为正方向) | public void setTranslationX(float translationX) |
在Y轴上平移(控件为原点向下为正方向) | public void setTranslationY(float translationY) |
在X轴上缩放 | public void setScaleX(flaot scaleX) |
在Y轴上缩放 | public void setScaleY(float scaleY) |
-
注意:
- 如果使用ObjectAnimator来进行自定义动画,在要操作的控件中必须存在对应属性的set函数,而且参数类型必须与构造所使用的ofFloat()或者ofInt()函数一致
- set函数必须使用驼峰命名法,再通过反射找到相应的set方法。
-
ObjectAnimator动画原理:
-
从图中我们可以看出ObjectAnimator的set相当于监听器的功能,但是相应的控件操作还是需要自己实现
-
首先我们看一下setScaleY()是如何实现的
public void setScaleY(float scaleY) {
if (scaleY != getScaleY()) {
scaleY = sanitizeFloatPropertyValue(scaleY, "scaleY");
invalidateViewProperty(true, false);
mRenderNode.setScaleY(scaleY);
invalidateViewProperty(false, true);
invalidateParentIfNeededAndWasQuickRejected();
notifySubtreeAccessibilityStateChangedIfNeeded();
}
}
- 自定义ObjectAnimator属性:
- 三个构造函数:
public static ObjectAnimator ofFloat(Object target, String propertyName,float... values);
public static ObjectAnimmator ofInt(Object target, String propertyName, int... values);
public static ObjectAnimator ofObject(Object target, String propertyName, TypeEvaluator evaluator, Object... values);
-
相比于ValueAnimator, ObjectAnimator的每个构造函数中多了一个propertyName属性,用于指定所要操作的属性
-
使用流程:
- 比如自定义一个动画,首先要实现setXXX函数
- 接着如果有Evaluator就实现一个Evaluator
- 之后调用相应的构造函数,使得其中Evaluator负责返回相应的数值
- 数值返回给setXXX函数,从而改变相应的位置
-
有了set函数那么何时能调用他的get函数:
- 当我们给动画值设定一个值的时候,他才会调用属性对应的get函数来得到动画初始值,如果没有初始值,系统会自动调用默认值
- 如果是 ofInt()或者是ofFloat()可以使用默认值0,0.0f, 但是如果使用的是自定义动画比如Point类型,就不存在系统的默认值,所以就会报错