- 上次提到IntEvaluator和FloatEvaluator,除了这两种Evaluator外,android.animation包下还有另外一个Evaluator, 名字为ArgbEvaluator,它是用来实现颜色值过度转换的。
private void doAnimator(){
final ValueAnimator valueAnimator = ValueAnimator.ofInt(0xffffff00,
0xff0000ff);
valueAnimator.setEvaluator(new ArgbEvaluator());
valueAnimator.setDuration(1000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = (int) valueAnimator.getAnimatedValue();
textView.setBackgroundColor(curValue);
}
});
valueAnimator.start();
}
- 注意:必须使用ValueEvaluator.ofInt()函数来定义颜色的取值范围,并且颜色必须包括A,R,G,B 4个值
- 写完了一个例子我们看一下原理吧:
*
public Object evaluate(float fraction, Object startValue, Object endValue) {
//第一部分求出A, R, G, B色彩的初始值
int startInt = (Integer) startValue;
float startA = ((startInt >> 24) & 0xff) / 255.0f;
float startR = ((startInt >> 16) & 0xff) / 255.0f;
float startG = ((startInt >> 8) & 0xff) / 255.0f;
float startB = ( startInt & 0xff) / 255.0f;
//第二部分求出A,R,G,B的结束值
int endInt = (Integer) endValue;
float endA = ((endInt >> 24) & 0xff) / 255.0f;
float endR = ((endInt >> 16) & 0xff) / 255.0f;
float endG = ((endInt >> 8) & 0xff) / 255.0f;
float endB = ( endInt & 0xff) / 255.0f;
// convert from sRGB to linear
startR = (float) Math.pow(startR, 2.2);
startG = (float) Math.pow(startG, 2.2);
startB = (float) Math.pow(startB, 2.2);
endR = (float) Math.pow(endR, 2.2);
endG = (float) Math.pow(endG, 2.2);
endB = (float) Math.pow(endB, 2.2);
//根据当前的进度求出对应的数值
// compute the interpolated color in linear space
float a = startA + fraction * (endA - startA);
float r = startR + fraction * (endR - startR);
float g = startG + fraction * (endG - startG);
float b = startB + fraction * (endB - startB);
// convert back to sRGB in the [0..255] range
a = a * 255.0f;
r = (float) Math.pow(r, 1.0 / 2.2) * 255.0f;
g = (float) Math.pow(g, 1.0 / 2.2) * 255.0f;
b = (float) Math.pow(b, 1.0 / 2.2) * 255.0f;
return Math.round(a) << 24 | Math.round(r) << 16 | Math.round(g) << 8 | Math.round(b);
}
- ValueAnimator进阶—ofObject
- 该方法可以传入任何类型的变量,函数定义如下:
public static ValueAnimator ofObject(TypeEvaluator evaluator, Object...values)
//第一个参数是自定义的Evaluator; 第二个参数是可变长参数,属于Object类型
- 示例:
public Character evaluate(float fraction, Character startValue, Character endValue) {
int startInt = (int)startValue;
int endInt = (int)endValue;
int curValue = (int) (startInt+fraction*(endInt-startInt));
char result = (char)curValue;
return result;
}
private void doChangeLetter() {
final ValueAnimator valueAnimator = ValueAnimator.ofObject(new CharEvaluator(), new Character('A'), new Character('Z'));
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
char text = (Character)valueAnimator.getAnimatedValue();
textView.setText(String.valueOf(text));
}
});
valueAnimator.setDuration(1000);
valueAnimator.setInterpolator(new AccelerateInterpolator());
valueAnimator.start();
}
- 实现一个简单的抛物运动:
class FallingBallEvaluator implements TypeEvaluator<Point> {
private Point point = new Point();
//pao'wu
@Override
public Point evaluate(float fraction, Point startValue, Point endValue) {
point.x = (int)(startValue.x + fraction*(endValue.x-startValue.x));
if(fraction*2<=1) {
point.y = (int) (startValue.y + fraction *2* (endValue.y - startValue.y));
}else{
point.y = endValue.y;
}
return point;
}
}
private void doAnimStart() {
final ValueAnimator valueAnimator = ValueAnimator.ofObject(new FallingBallEvaluator(), new Point(0, 0), new Point(500, 500));
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Point curValue = (Point) valueAnimator.getAnimatedValue();
imageView.layout(curValue.x, curValue.y, curValue.x+imageView.getWidth(), curValue.y+imageView.getHeight());
}
});
valueAnimator.setDuration(1000);
valueAnimator.start();
}