# android那些事--属性动画04TypeEvaluator的使用

## 理论介绍

``````public class FloatEvaluator implements TypeEvaluator<Number> {

/**
* This function returns the result of linearly interpolating the start and end values, with
* <code>fraction</code> representing the proportion between the start and end values. The
* calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,
* where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
* and <code>t</code> is <code>fraction</code>.
*
* @param fraction   The fraction from the starting to the ending values
* @param startValue The start value; should be of type <code>float</code> or
*                   <code>Float</code>
* @param endValue   The end value; should be of type <code>float</code> or <code>Float</code>
* @return A linear interpolation between the start and end values, given the
*         <code>fraction</code> parameter.
*/

public Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
}
``````

``````public class IntEvaluator implements TypeEvaluator<Integer> {

/**
* This function returns the result of linearly interpolating the start and end values, with
* <code>fraction</code> representing the proportion between the start and end values. The
* calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,
* where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
* and <code>t</code> is <code>fraction</code>.
*
* @param fraction   The fraction from the starting to the ending values
* @param startValue The start value; should be of type <code>int</code> or
*                   <code>Integer</code>
* @param endValue   The end value; should be of type <code>int</code> or <code>Integer</code>
* @return A linear interpolation between the start and end values, given the
*         <code>fraction</code> parameter.
*/

public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int startInt = startValue;
return (int)(startInt + fraction * (endValue - startInt));
}
}
``````

## 实际使用

1. 自定义一个Evaluator,完成Point平滑的过渡
2. 在自定义View中启动Point的动画,得到不断更新的Point对象
3. 更新新的Point对象重新对View进行绘制

``````public class PointEvaluator implements TypeEvaluator<Point> {
@Override
public Point evaluate(float fraction, Point startValue, Point endValue) {
float resultX = startValue.getX() + fraction * (endValue.getX() - startValue.getX());
float resultY = startValue.getY() + fraction * (endValue.getY() - startValue.getX());
return new Point(resultX, resultY);
}
}

``````

Point对象辅助性完成

``````public class Point {
private float x;
private float y;

public Point(float x, float y) {
this.x = x;
this.y = y;
}

public float getX() {
return x;
}

public void setX(int x) {
this.x = x;
}

public float getY() {
return y;
}

public void setY(int y) {
this.y = y;
}
}

``````

``````public class MyView extends View {

private Paint mPaint;
private Point mPoint;

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);
@Override
public void onAnimationUpdate(ValueAnimator animation) {

mPoint = ((Point) animation.getAnimatedValue());
LogUtil.i(mPoint.getX()+"------"+mPoint.getY());
invalidate();
}
});
animator.setDuration(5000);
animator.start();
}
}
``````