通過對ValueAnimator
和ObjectAnimator
的使用,了解到在獲取動畫對象時只需要傳入起始和結束值系統(tǒng)就會自動完成值的平滑過渡,這個平滑過渡的完成就是靠TypeEvaluator
這個類.還是一樣先看一下這個接口的介紹.
理論介紹
這里寫圖片描述
再看下android源碼中FloatEvaluator
和IntEvaluator
這兩個子類是如何實現的.
這個是
FloatEvaluator
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);
}
}
這個是
IntEvaluator
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));
}
}
可以看出這是兩個非常實在的類,哈哈.
用結束值減去初始值,算出它們之間的差值朽们,然后乘以fraction這個系數怀读,再加上初始值,那么就得到當前動畫的值了
實際使用
簡單需求:自定義一個View,在View中有一個Point對象用于管理坐標,然后在onDraw()方法中根據Point坐標進行繪制.
分析:我們已經知道數據的平滑過渡是怎么產生的了,那么如果可以對Point對象進行平滑過渡則自定義View就可以實現需要的動畫效果.
- 自定義一個Evaluator,完成Point平滑的過渡
- 在自定義View中啟動Point的動畫,得到不斷更新的Point對象
- 更新新的Point對象重新對View進行繪制
自定義的Evaluator類
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;
}
}
最終的自定義的View
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);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mPoint = ((Point) animation.getAnimatedValue());
LogUtil.i(mPoint.getX()+"------"+mPoint.getY());
invalidate();
}
});
animator.setDuration(5000);
animator.start();
}
}
這里寫圖片描述