-
从之前的ValueAnimator和ObjectAnimator中都有一个函数ofPropertyValuesHolder(PropertyValuesHolder…values)
-
相比之下ObjectAnimator的ofPropertyValuesHolder()函数使用较多
-
PropertyValuesHolder
- 它其中保存了动画过程中所需要操作的属性和对应的值,我们通过ofFloat(Object object, String propertyName, float… values)构造的动画,ofFloat()内部是通过将传入的参数封装成PropertyValuesHolder实例来保存动画的=状态的,之后就会产生针对PropertyValuesHolder的操作。
-
创建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.. value)
public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values)
- ofFloat() ofInt()函数:
propertyName: 表示ObjectAnimator需要操作的属性名,即对应的ObjectAnimator需要查找的setProperty()函数。
values:属性所对应的参数,同样是可变长参数,如果只指定一个那么会调用相应的get函数来获取默认初始值
- 了解上述的可知PropertyValuesHolder只比ObjectAnimator的ofFloat()函数少了一个target,所以我们可以通过ofPropertyValuesHolder将其引入
public staticObjectAnimator ofPropertyValuesHoldder(Object target, PropertyValuesHolder... values)
- target: 需要执行动画的组件
- values:可变长参数,可以传入多个PropertyValuesHolder实例,由于每个PropertyValuesHolder实例都会针对一个属性执行动画操作,所以如果传入多个PropertyValuesHolder,则会对控件的多个属性同时进行进行操作
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofFloat("Rotation",60f, -60f);
PropertyValuesHolder propertyValuesHolder1 = PropertyValuesHolder.ofFloat("alpha", 0.1f, 1f);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(textView, propertyValuesHolder, propertyValuesHolder1);
objectAnimator.setDuration(100);
objectAnimator.start();
}
});
-
经过上面的代码可知,propertyValuesHolder就是将原来的target后面的部分进行了封装,两个动画同时进行相当于进行playTogether()
-
PropertyValuesHolder之ofObject()
- 概述:
public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evvalutator, Object.... values)
-
参数
- propertyName:ObjectAnimator动画操作的属性名
- evaluator: Evaluator实例。Evaluator是根据当前动画进度计算出当前值的类,可以使用系统自带的IntEvaluator、FloatEvaluator也可以自定义
- values:可变长参数,表示操作动画属性的值
它各个参数与ObjectAnimator.ofObject()函数的参数类似,只是少了target,所以根据上面的例子可知,他也是对后半部分的封装。
-
keyframe: 关键帧(方便自定义插值器)
- 表示在哪个时间点应该在哪个位置上
-
生成方式:
//fraction :表示当前的显示进度, 即在插值器中getInterpolation()函数的返回值
//value:表示动画当前所在的数值位置
//Ketframe.ofFloat(0,0)表示动画进度为0,动画所在的数值位置为0;
//Keyframe.ofFloat(1f, 0)表示动画结束时,动画所在的数值位置为0
public static Keyframe ofFloat(float fraction, float value)
- PropertyValuesHolder使用Keyfrmae对象:
//propertyName:动画索要操作的属性名
//values: Keyframe 的列表,PropertyValuesHolder会根据每个Keyframe的设定,定时将指定的值输出给动画
public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe.... values);
- 所以简单使用Keyframe
Keyframe frmae0 = Keyframe.ofFloat(0f, 0);
Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);
Keyframe frame2 = Keyframe.ofFloat(1, 0);
PropertyValueHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation", frame0, frame1, frame2);
Animation animator = ObjectAnimator.ofPropertyValuesHolder(mImage, frameHolder);
animator.setDuration(1000);
animator.start();
- 实现步骤生成Keyframe对象
- 利用PropertyValuesHolder.ofKeyframe()函数生成PropertyValueHolder
- 之后使用ObjectAnimator.ofPropertyValuesHolder()生成对应的ObjectAnimator
eg:
Keyframe frame0 = Keyframe.ofFloat(0f, 0);
Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);
Keyframe frame2 = Keyframe.ofFloat(0.2f, 20f);
Keyframe frame3 = Keyframe.ofFloat(0.3f, -20f);
Keyframe frame4 = Keyframe.ofFloat(0.4f, 20f);
Keyframe frame5 = Keyframe.ofFloat(0.5f, -20f);
Keyframe frame6 = Keyframe.ofFloat(0.6f, 20f);
Keyframe frame7 = Keyframe.ofFloat(0.7f, -20f);
Keyframe frame8 = Keyframe.ofFloat(0.8f, 20f);
Keyframe frame9 = Keyframe.ofFloat(0.9f, -20f);
Keyframe frame10 = Keyframe.ofFloat(1,0);
PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation", frame0,frame1,frame2,frame3,frame4,frame5,frame6,frame7,frame8,frame9,frame10);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(imageView, frameHolder);
objectAnimator.setDuration(1000);
objectAnimator.start();
- Keyframe的ofFloat()和ofInt()的用法:
public static Keyframe ofFloat)float fraction);
public static Keyframe ofFloat(float fraction , float value);
public static Keyframe ofInt(float fraction);
public static Keyframe ofFloat(float fraction, int value)
-
两个参数的构造函数和上面的相同
-
来看一个参数的构造函数:使用这个构造函数还需要使用其他函数来辅助使用,比如setFraction(float fraction)和setValue(Object value), 可以通过setValue来设置当前动画进度位置所对应的值,比较灵活。
-
插值器:
public void setInterpolator(TimeInterpolator interpolator)
- 如果给当前的Keyframe设置插值器,那么再从上一个Keyframe到当前的Keyframe的中间值计算过程中,,使用的就是该插值器
Keyframe frame1 = Keyframe.ofFloat(0f, 0);
Keyframe frame2 = Keyframe.ofFloat(0.1f, 20f);
//在frame1到frame2之间就是使用的弹跳插值器,就近原则
frame2.setInterpolator(new BounceInterpolator);
- 同样Keyframe也有ofObject的方法:
public static Keyframe ofObject(float fracction)
public static Keyframe ofObject(float fraction, Object value)
- 尝试:
- 去掉第零帧,以第一帧为起始位置
- 去掉结束帧,以最后一帧为结束帧
- 只保留一中间帧,至少需要两帧 ,否则会报数组越界的错误,中间帧 为两帧可以运行
eg: Keyframe实现多动画同时运行:
Keyframe frame0 = Keyframe.ofFloat(0f, 0);
Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);
Keyframe frame2 = Keyframe.ofFloat(0.2f, 20f);
Keyframe frame3 = Keyframe.ofFloat(0.3f, -20f);
Keyframe frame4 = Keyframe.ofFloat(0.4f, 20f);
Keyframe frame5 = Keyframe.ofFloat(0.5f, -20f);
Keyframe frame6 = Keyframe.ofFloat(0.6f, 20f);
Keyframe frame7 = Keyframe.ofFloat(0.7f, -20f);
Keyframe frame8 = Keyframe.ofFloat(0.8f, 20f);
Keyframe frame9 = Keyframe.ofFloat(0.9f, -20f);
Keyframe frame10 = Keyframe.ofFloat(1);
frame10.setValue(0);
frame5.setInterpolator(new BounceInterpolator());
PropertyValuesHolder rotationFrameHolder = PropertyValuesHolder.ofKeyframe("rotation", frame0, frame1,frame2,frame3,frame4,frame5,frame6,frame7,frame8,frame9,frame10);
Keyframe scaleXFrame0 = Keyframe.ofFloat(0f,1);
Keyframe scaleXFrame1 = Keyframe.ofFloat(0.1f,1.1f);
Keyframe scaleXFrame9 = Keyframe.ofFloat(0.9f,1.1f);
Keyframe scaleXFrame10 = Keyframe.ofFloat(1,1);
PropertyValuesHolder scaleFrameHolder1 = PropertyValuesHolder.ofKeyframe("ScaleX", scaleXFrame0, scaleXFrame1,scaleXFrame9,scaleXFrame10);
Keyframe scaleYFrame0 = Keyframe.ofFloat(0f, 1);
Keyframe scaleYFrame1 = Keyframe.ofFloat(0.1f, 1.1f);
Keyframe scaleYFrame9 = Keyframe.ofFloat(0.9f, 1.1f);
Keyframe scaleYFrame10 = Keyframe.ofFloat(1, 1);
PropertyValuesHolder scaleFrameHolder2 = PropertyValuesHolder.ofKeyframe("ScaleY",scaleYFrame0, scaleYFrame1,scaleYFrame9,scaleYFrame10);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(imageView, rotationFrameHolder, scaleFrameHolder1,scaleFrameHolder2);
objectAnimator.setDuration(3000);
objectAnimator.start();