如果看了objectanimator(真正的劳动者)和TypeEvaluator的使用那么你对自定义TypeEvaluator和对任意属性做动画这两个概念就应该很熟悉了.下面这个例子就是对二者的综合使用.
我们知道补间动画的效果很局限于移动,缩放,旋转,和淡入淡出这四种效果.通过ObjectAnimator我们可以完成对任意属性设置动画效果,通过TypeEvaluator我们可以改变动画的效果显示状态.
需求:移动小球,并改变小球颜色.
blic class MyView extends View {
private Paint mPaint;
private Point mPoint;
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
mPaint.setColor(Color.parseColor(color));
invalidate();
}
public MyView(Context context) {
super(context);
init();
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.BLUE);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mPoint == null) {
mPoint = new Point(50, 50);
drawCircle(canvas);
startAnimation();
} else {
drawCircle(canvas);
}
}
private void drawCircle(Canvas canvas) {
canvas.drawCircle(mPoint.getX(), mPoint.getY(), 50, mPaint);
}
private void startAnimation() {
Point startPoint = new Point(50, 50);
Point endPoint = new Point(getWidth() - 50, getHeight() - 50);
ValueAnimator animator = ValueAnimator
.ofObject(new PointEvaluator(), startPoint, endPoint);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mPoint = ((Point) animation.getAnimatedValue());
LogUtil.i(mPoint.getX() + "------" + mPoint.getY());
invalidate();
}
});
ObjectAnimator colorAnimator = ObjectAnimator.ofObject(this, "color", new ColorEvaluator(),
"#0000ff", "#ff0000");
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(animator).with(colorAnimator);
animatorSet.setDuration(5000);
animatorSet.start();
}
}
颜色的控制
public class ColorEvaluator implements TypeEvaluator {
private int currentRed = -1;
private int currentGreen = -1;
private int currentBlue = -1;
@Override
public String evaluate(float fraction, String startValue, String endValue) {
int startRed = Integer.parseInt(startValue.substring(1, 3), 16);
int startGreen = Integer.parseInt(startValue.substring(3, 5), 16);
int startBlue = Integer.parseInt(startValue.substring(5, 7), 16);
int endRed = Integer.parseInt(endValue.substring(1, 3), 16);
int endGreen = Integer.parseInt(endValue.substring(3, 5), 16);
int endBlue = Integer.parseInt(endValue.substring(5, 7), 16);
if (currentRed == -1) {
currentRed = startRed;
}
if (currentBlue == -1) {
currentBlue = startBlue;
}
if (currentGreen == -1) {
currentGreen = startGreen;
}
int diffRed = Math.abs(startRed - endRed);
int diffGreen = Math.abs(startGreen - endGreen);
int diffBlue = Math.abs(startBlue - endBlue);
if (currentRed != endRed) {
currentRed = getCurrentColor(startRed, endRed, diffRed, 0, fraction);
} else if (currentGreen != endGreen) {
currentGreen = getCurrentColor(startGreen, endGreen, diffGreen, diffRed, fraction);
} else if (currentBlue != endBlue) {
currentBlue = getCurrentColor(startBlue, endBlue, diffBlue, diffRed + diffGreen, fraction);
}
String currentColor = "#" + getHexString(currentRed) +
getHexString(currentGreen) +
getHexString(currentBlue);
LogUtil.i(currentColor);
return currentColor;
}
private int getCurrentColor(int startColor, int endColor,
int diffColor, int offset, float fraction) {
int currentColor = 0;
if (startColor > endColor) {
currentColor = (int) (startColor - (fraction * diffColor - offset));
if (currentColor < endColor) {
currentColor = endColor;
}
} else {
currentColor = (int) (startColor + (fraction * diffColor - offset));
if (currentColor > endColor) {
currentColor = endColor;
}
}
return currentColor;
}
private String getHexString(int value) {
String hexString = Integer.toHexString(value);
if (hexString.length() == 1) {
hexString = "0" + hexString;
}
return hexString;
}
}
效果: