ProoertyValuesHolder
- ValueAnimator、ObjectAnimator除了这些创建Animator实例的方法以外,都还有一个方法:
// valueAnimator的
public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values)
// ObjectAnimator的
public static ObjectAnimator ofPropertyValuesHolder(Object target,PropertyValuesHolder... values)
//两者使用差不多,下面都已ObjectAnimator中的方法举例学习。
PropertyValuesHolder这个类的意义就是,它其中保存了动画过程中所需要操作的属性和对应的值。
我们通过ObjectAnimator.ofFloat(Object target, String propertyName, float… values)构造的动画,
ofFloat()的内部实现其实就是将传进来的参数封装成PropertyValuesHolder实例来保存动画状态。
在封装成PropertyValuesHolder实例以后,后期的各种操作也是以PropertyValuesHolder为主的。
- ProoertyValuesHolder中构造实例的方法:
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)
作用:
- 保存动画所需要操作的:属性和对应的值。
- ObjectAnimator中的ofPropertyValuesHolder(Object target,PropertyValuesHolder... values)方法,可以传入多个holder参数,其实可以以此代替AnimatorSet动画集合。
//将需要操作的多个属性和值封装起来,一起放到ObjectAnimator中,相当于set操作。
PropertyValuesHolder rotateHolder = PropertyValuesHolder.ofFloat("Rotation", 0, 360, 0, -360,0);
PropertyValuesHolder scaleXHolder = PropertyValuesHolder.ofFloat("scaleX", 1, 2, 1,2,1);
PropertyValuesHolder scaleYHolder = PropertyValuesHolder.ofFloat("scaleY", 1, 2, 1,2,1);
ObjectAnimator objectAnim = ObjectAnimator.ofPropertyValuesHolder(ivHolderTarget,rotateHolder, scaleXHolder, scaleYHolder);
objectAnim.setDuration(2000);
objectAnim.setInterpolator(new LinearInterpolator());
objectAnim.start();
KeyFrame:主要帧。
//构造PropertyValuesHolder实例,还有这样一个方法。
public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values)
如果想要更精确的控制动画,想要控制整个动画过程的某个点或某个时段达到的值,可以通过自定义插值器或估值器来实现,但是那样又有些费事,并且不容易计算这段时间内值的变化。 这时可以用Keyframe来实现,即设置好某个时间点和值,系统会自动计算该点和上个点之间,值的变化。
/***
* 实现左右摇晃,每边最后有震动的效果。
* 摇晃角度100度:0.2f/0.2~0.4/0.4~0.5,分别设置不同的角度和加速器。
* 每个比例点达到哪个角度,这在估值器中也能做到,但是需要自己算每个时间段内值的变化过程。
* KeyFrame可以设置好 比例-值 以后,系统根据默认或设置的加速器改变:上个点和该点内的值如何变换。
* 这样可以更精确的控制动画过程,同时也不用自己费劲去计算值因该如何变换。
*/
Keyframe kfRotation1 = Keyframe.ofFloat(0, 0); //第一帧,如果没有该帧,会直接跳到第二帧开始动画。
//第二帧 0.2f时达到60度,线性加速应该作用于从0~0.2f的这段时间,而不是作用在0.2~0.4f这段。因为已经定好60度是要的结果了,那么实现就应该在前面这段。猜测,没有实际做过对比。
Keyframe kfRotation2 = Keyframe.ofFloat(0.2f, 60);
kfRotation2.setInterpolator(new LinearInterpolator());
Keyframe kfRotation3 = Keyframe.ofFloat(0.4f, 100);
kfRotation3.setInterpolator(new BounceInterpolator());
Keyframe kfRotation4 = Keyframe.ofFloat(0.5f, 0);
kfRotation4.setInterpolator(new LinearInterpolator()); //最少有2帧
Keyframe kfRotation5 = Keyframe.ofFloat(0.7f, -60);
kfRotation5.setInterpolator(new LinearInterpolator());
Keyframe kfRotation6 = Keyframe.ofFloat(0.9f, -100);
kfRotation6.setInterpolator(new BounceInterpolator());
Keyframe kfRotation7 = Keyframe.ofFloat(1f, 0); //最后一帧,如果没有该帧,会已最后一个KeyFrame做结尾。
kfRotation7.setInterpolator(new LinearInterpolator());
Keyframe kfScaleX1 = Keyframe.ofFloat(0, 1);
Keyframe kfScaleX2 = Keyframe.ofFloat(0.01f,2.8f);
Keyframe kfScaleX3 = Keyframe.ofFloat(0.8f,2.0f);
Keyframe kfScaleX4 = Keyframe.ofFloat(1f,1.0f);
Keyframe kfScaleY1 = Keyframe.ofFloat(0, 1);
Keyframe kfScaleY2 = Keyframe.ofFloat(0.01f,2.8f);
Keyframe kfScaleY4 = Keyframe.ofFloat(0.8f,2.0f);
Keyframe kfScaleY5 = Keyframe.ofFloat(1f,1.0f);
PropertyValuesHolder rotationHolder = PropertyValuesHolder.ofKeyframe("rotation", kfRotation1, kfRotation2, kfRotation3,kfRotation4, kfRotation5, kfRotation6, kfRotation7);
PropertyValuesHolder scaleXHolder = PropertyValuesHolder.ofKeyframe("scaleX", kfScaleX1, kfScaleX2, kfScaleX3, kfScaleX4);
PropertyValuesHolder scaleYHolder = PropertyValuesHolder.ofKeyframe("scaleY", kfScaleY1, kfScaleY2, kfScaleY4, kfScaleY5);
ObjectAnimator objectAnim = ObjectAnimator.ofPropertyValuesHolder(ivHolderTarget, rotationHolder, scaleXHolder, scaleYHolder);
objectAnim.setDuration(1500);
objectAnim.start();