一时间插值器(TimeInterpolator)的作用是根据时间流逝的百分比计算出动画进度的百分比。
public class LinearInterpolator implements Interpolator{ @Override public float getInterpolation(float v) { return v; } }如线性插值器,输入v则返回v.(项目总时间过了40%,则项目进度也达到了40%)
二。类型估值器(TypeEvaluator)的作用是根据属性值改变的百分比计算出改变后的属性值。
public class IntEvaluator implements TypeEvaluator<Integer>{
public Integer evaluate(float fraction,Integer startValue,Integer endValue){
int startInt = startValue;
return (int)(startInt + fracion * (endValue - startValue));
}
}
属性动画通过以上两类就可以完成输入当前时间计算出当前属性最终值得计算。
三。属性动画ObjectAnimator的start方法中,
首先判断当前动画,等待动画,延迟动画中是否有和当前动画相同的动画,有就把该相同动画取消。接着调用父类ValueAnimator的start方法
在ValueAnimator的start方法中要使用handler,所以要保证运行在有 Looper的线程中
它会调用一个run方法和底层交互,并调用ValueAnimator的doAnimationFrame方法。
doAnimationFrame中会根据不同的状态返回或计算当前的时间作为参数调用animateValue方法
animateValue会调用calulateValue方法计算每帧动画对应的属性值,
最后会以反射的方式调用set方法对对象的属性进行设置
如果属性的初始值没有设置,则get方法会被调用,在PropertyValuesHolder的setupValue中。
动画下一帧到来时,set方法被调用,PropertyValuesHolder的setAnimatedValue中。
四。对象可以对其任何属性使用属性动画,但要保证该对象具有该属性的set和get方法,并且set方法会以某种方式最终影响到该对象的UI。
1.当对象不具有set,get属性时,可以用类包装该类,使其间接具有get和set方法
//包装View类 用于给属性动画调用 从而包装了set get
public class ViewWrapper {
private View target;
public ViewWrapper(View target) {
this.target = target;
}
public int getWidth() {
return target.getLayoutParams().width;
}
public void setWidth(int width) {
target.getLayoutParams().width = width;
target.requestLayout();
}
}
//使用:
ViewWrapper wrapper = new ViewWrapper(mButton);
ObjectAnimator.ofInt(mButton,"width",500).setDuration(3000).start();
二采用ValueAnimator,监听动画过程,自己实现属性变化
ValueAnimator可以自己产生值,但要给其设定初始值,结束值,以及周期,就可以让它开始运作
然后通过监听,在其产生每一个值时人工改变对象的属性值。
private void performAnimate(final View target, final int start, final int end) {
ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100);
valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
// 持有一个IntEvaluator对象,方便下面估值的时候使用
private IntEvaluator mEvaluator = new IntEvaluator();
@Override
public void onAnimationUpdate(ValueAnimator animator) {
// 获得当前动画的进度值,整型,1-100之间
int currentValue = (Integer) animator.getAnimatedValue();
Log.d(TAG, "current value: " + currentValue);
// 获得当前进度占整个动画过程的比例,浮点型,0-1之间
float fraction = animator.getAnimatedFraction();
// 直接调用整型估值器通过比例计算出宽度,然后再设给Button
target.getLayoutParams().width = mEvaluator.evaluate(fraction, start, end);
target.requestLayout();
}
});
valueAnimator.setDuration(5000).start();
}
三。最简单的还是给该对象该属性增加set和get方法,如果可以的话
参考:Android开放艺术探索