- Android 属性动画Property Animation(上)
- Android 属性动画Property Animation(中)
本篇来介绍一下属性动画中另一个重要的类ObjectAnimator~
- ObjectAnimator
ObjectAnimator是 ValueAnimator的子类,它是可以直接对任意对象的任意属性进行动画操作的,因为ValueAnimator是父类,所以ValueAnimator中可以使用的方法在ObjectAnimator中也是可以使用的,ObjectAnimator可以用XML表示,创建object_anim.xml如下:
代码中调用XML文件:
ObjectAnimator objectAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.object_anim);
objectAnimator.setTarget(myObject);
objectAnimator.start();
如果想创建更复杂一些的动画,需要用到PropertyValuesHolder来对各个属性分别做动画,如:
如果想更复杂一些,还要用到keyframe (关键帧),fraction是当前进度,取值范围(0,1),插值器interpolator 是可选的,默认是 AccelerateDecelerateInterpolator,示例:
代码中使用ObjectAnimator:
//ofFloat(Object target, String propertyName, float... values)
//第一个参数为object类型的target,这里是textview
//第二个参数是要做动画的属性值
//最后一个可以传入任意个数的参数,动画在他们数值之间过渡
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(tv_text, "rotation", 0f, 20f, -20f, 20f, -20f, 0f);
//动画时长
objectAnimator.setDuration(3000);
//动画重复次数
objectAnimator.setRepeatCount(2);
//动画重复模式
objectAnimator.setRepeatMode(ValueAnimator.RESTART);
//设置动画插值器
objectAnimator.setInterpolator(new AccelerateInterpolator());
//设置监听器
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
Log.e("TTT", "value is " + value);
}
});
//启动动画
objectAnimator.start();
ofFloat()中第二个参数传入属性值的是"rotation",那么这个参数都可以用哪些值呢?答案是任何值!因为ObjectAnimator针对于任意对象的,它的工作就是不断地向某个对象中的某个属性进行赋值,然后对象根据属性值的改变再来决定如何展现出来。系统不会根据这个属性值名称去查找,而是会查找对应的get和set方法。
上面代码效果图:
上面使用的是ObjectAnimator.ofFloat()来创建浮点数值的ObjectAnimator实例,那么如果想创建自定义object的ObjectAnimator实例呢?这时就要用ObjectAnimator.ofObject()来创建了,如:
ObjectAnimator ofObject(Object target, String propertyName,TypeEvaluator evaluator, Object... values)
这里要用到自定义Evaluator 了,Android 属性动画Property Animation(上) 中已经介绍过,Evaluator通过给定的动画起始值(startValue)和结束值(endValue)以及动画当前进度(fraction)来计算当前动画的进度值。先来看下几个常用的Evaluator,
IntEvaluator:
public class IntEvaluator implements TypeEvaluator {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int startInt = startValue;
return (int)(startInt + fraction * (endValue - startInt));
}
}
FloatEvaluator:
public class FloatEvaluator implements TypeEvaluator {
public Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
}
返回的当前进度值=起始值+(结束值-起始值) x 当前进度,ArgbEvaluator也是一样道理。如果用ofInt()来定义动画,动画中的进度值应该都是整形的,如果用ofFloat()来定义动画,那么动画中的值也都是浮点型的。以ofFloat(0.0f,1.0f)为例:起始值为0.0f,结束值是1.0f,假如当前进度(fraction)为50%,则当前进度值=0.0f+(1.0f-0.0f)x 0.5=0.5,在AnimatorUpdateListener监听器中通过animation.getAnimatedValue()函数拿到Evaluator中返回的值,如果需要自定义Evaluator,则需要实现TypeEvaluator接口:
public class MyEvalutor implements TypeEvaluator {
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
return null;
}
}
下面创建一个自定义object的ObjectAnimator例子,先定义一个ObInfo类:
public class ObInfo implements Serializable {
public int color;//用来定义颜色
public float x; //用来定义X轴
public float y; //用来定义Y轴
public ObInfo(int color, float x, float y) {
this.color = color;
this.x = x;
this.y = y;
}
}
接着自定义TypeEvaluator :
public class MyEvalutor implements TypeEvaluator {
@Override
public ObInfo evaluate(float fraction, ObInfo startValue, ObInfo endValue) {
float x = startValue.x + fraction * (endValue.x - startValue.x);
float y = startValue.y + fraction * (endValue.y - startValue.y);
int color = (int) (startValue.color + fraction * (endValue.color - startValue.color));
return new ObInfo(color, x, y);
}
}
最后实现动画:
ObInfo info1 = new ObInfo(0xffffff00, 500, 200);
ObInfo info2 = new ObInfo(0xff0000ff, 500, 1000);
ValueAnimator animator = ValueAnimator.ofObject(new MyEvalutor(), info1, info2, info1);
animator.setDuration(4000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
ObInfo info = (ObInfo) animation.getAnimatedValue();
tv_text.layout(tv_text.getLeft(), (int) info.y, tv_text.getRight(), (int) (info.y + tv_text.getHeight()));
tv_text.setTextColor(info.color);
}
});
animator.start();
文字先往下移动,再返回原处,移动过程中颜色也不断变化,效果图:
如果想监听动画过程只需添加监听器:
objectAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
//动画开始前调用
}
@Override
public void onAnimationEnd(Animator animation) {
//动画结束时调用
}
@Override
public void onAnimationCancel(Animator animation) {
//动画取消时调用
}
@Override
public void onAnimationRepeat(Animator animation) {
//动画重复执行时调用
}
});
如果只想用其中的一个,只需改成适配器类AnimatorListenerAdapter即可:
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
}
});
常用方法 | 备注 |
---|---|
ofFloat、ofInt、ofArgb、ofObject、ofPropertyValuesHolder | ofFloat(),ofInt(),ofArgb(),ofObject(),ofPropertyValuesHolder()分别是用来创建浮点型、整形、颜色值、自定义object、包含PropertyValuesHolder的animator实例 |