PropertyAnimator学习之ObjectAnimator

一、ObjectAnimator基本使用

ObjectAnimator继承自ValueAnimator,它与ValueAnimator的区别在于可以直接作用于控件,无需在监听器中手动改变控件的属性。

public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) 
target是要操作的控件对象,propertyName是要操作的控件属性,values与ValueAnimator中的定义相同,表示属性值的变化。其中属性参数并不代表控件有名为propertyName的属性,而是对该属性对应的set方法进行操作。假定属性值名为scaleX,则:

1.控件中需要有名为setScaleX的set方法,并且参数类型和values的类型一致;

2.set方法的命名要采用骆驼命名法,即set后的每个单词的首字母大写,其余字母小写;

调用set方法是在Evaluator计算出当前值之后,并将当前值作为参数传给set方法。仍以setScaleX为例,这里propertyName可以写成scaleX或ScaleX,即首字母大小写均可,而后面的字母大小写要严格依照set方法的名字。

ObjectAnimator调用set方法是通过反射来进行的,如果property名字或者参数类型不对,将会报异常找不到方法。

控件对象target可以是系统控件,也可以是自定义控件,但是必须要有相应的set方法才能对其做动画。

最后,如果values只传了一个参数,那么ObjectAnimator会去调用控件对象的get方法作为动画起始状态的值,此时target对象必需要有对应proptertyName的get方法,否则会出异常。

二、PropertyValuesHolder使用

ValueAnimator和ObjectAnimator还有一个ofPropertyValuesHolder方法来创建实例,实际上如果我们调用ofFloat或者ofInt方法,系统也会将传进来的值封装成PropertyValuesHolder,下面以ObjectAnimator来看PropertyvaluesHolder如何使用。

public static PropertyValuesHolder ofFloat(String propertyName, float... values)
public static PropertyValuesHolder ofInt(String propertyName, int... values) 
public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator,Object... values)
public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values)
可以看出每个PropertyValuesHolder对应着控件的一个属性和若干个属性值,与ObjectAnimator的ofFloat等方法类似,只是缺少target对象。

public static ObjectAnimator ofPropertyValuesHolder(Object target,PropertyValuesHolder... values)
而ObjectAnimator的创建可以传入多个PropertyValuesHolder,意味着可以同时对控件的多个属性进行操作。以下是同时对控件进行旋转和改变背景颜色的代码示例。

PropertyValuesHolder rotationHolder = PropertyValuesHolder.ofFloat("Rotation", 60f, -60f, 40f, -40f, -20f, 20f, 10f, -10f, 0f);
PropertyValuesHolder colorHolder = PropertyValuesHolder.ofInt("BackgroundColor", 0xffffffff, 0xffff00ff, 0xffffff00, 0xffffffff);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mTextView, rotationHolder, colorHolder);
animator.setDuration(3000);
animator.setInterpolator(new AccelerateInterpolator());
animator.start();

三、Keyframe的使用

我们可以通过自定义Interpolator和Evaluator来控制动画的变化速率,但是这需要复杂的数学计算。好在谷歌为我们提供了一个类Keyframe,意思是关键帧。所谓关键帧就是整个动画过程中若干个点的状态,有了关键帧,我们无需对整个动画过程中的每一点的状态进行控制,只需设置若干个关键帧,其他点的状态由系统来填充,Keyframe的生成方式为:

public static Keyframe ofFloat(float fraction, float value)
其中,fraction代表时间进度,value代表在当动画执行到该时间时属性值是多少。同样,Keyframe也有ofInt方法。

Keyframe需要结合PropertyValuesHolder来使用,使用过程如下:

第一步:生成Keyframe对象; 
第二步:利用PropertyValuesHolder.ofKeyframe()生成PropertyValuesHolder对象 
第三步:ObjectAnimator.ofPropertyValuesHolder()生成对应的Animator

下面是代码示例。

Keyframe frame0 = Keyframe.ofFloat(0f, 0);
Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);
Keyframe frame2 = Keyframe.ofFloat(1, 0);
PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation",frame0,frame1,frame2);
 Animator animator = ObjectAnimator.ofPropertyValuesHolder(mImage,frameHolder);
animator.setDuration(1000);
animator.start();
需要注意的是,Keyframe支持为每一个关键帧单独设置Interpolator,这个插值器生效的时间为从上一个关键帧到这个关键帧的动画过程中。

最后,Keyframe和PropertyValuesHolder都支持ofObject方法对非Float和Int的自定义类型进行处理,但是需要我们自己实现Evaluator来完成float型的进度值到我们自定义类型的属性值的转换。




你可能感兴趣的:(UI设计类,Android)