一. 简介 1.作用 一个接口,用来设置 属性值 从初始值过渡到结束值 的变化具体数值。
2.插值器与估值器区别
二. 系统的估值器 1.IntEvaluator:以整型的形式从初始值 - 结束值 进行过渡 1 2 3 4 5 6 public class IntEvaluator implements TypeEvaluator <Integer > { public Integer evaluate (float fraction, Integer startValue, Integer endValue) { int startInt = startValue; return (int )(startInt + fraction * (endValue - startInt)); } }
2.FloatEvaluator:以浮点型的形式从初始值 - 结束值 进行过渡 1 2 3 4 5 6 public class FloatEvaluator implements TypeEvaluator <Number > { public Float evaluate (float fraction, Number startValue, Number endValue) { float startFloat = startValue.floatValue(); return startFloat + fraction * (endValue.floatValue() - startFloat); } }
3.ArgbEvaluator:以Argb类型的形式从初始值 - 结束值 进行过渡 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 public class ArgbEvaluator implements TypeEvaluator { private static final ArgbEvaluator sInstance = new ArgbEvaluator(); @UnsupportedAppUsage public static ArgbEvaluator getInstance () { return sInstance; } public Object evaluate (float fraction, Object startValue, Object endValue) { 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 ; 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 ; 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 ); float a = startA + fraction * (endA - startA); float r = startR + fraction * (endR - startR); float g = startG + fraction * (endG - startG); float b = startB + fraction * (endB - startB); 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); } }
三. 自定义的估值器 1.本质 根据 插值器计算出当前属性值改变的百分比 & 初始值 & 结束值 来计算 当前属性具体的数值
2.具体实现方式 实现 TypeEvaluator接口 & 重写evaluate()
1 2 3 4 5 6 7 8 9 10 11 12 public interface TypeEvaluator <T > { public T evaluate (float fraction, T startValue, T endValue) ; }
在学习自定义估值器前,我们先来看一个已经实现好的系统内置差值器:浮点型估值器器:FloatEvaluator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class FloatEvaluator implements TypeEvaluator { public Object evaluate (float fraction, Object startValue, Object endValue) { float startFloat = ((Number) startValue).floatValue(); return startFloat + fraction * (((Number) endValue).floatValue() - startFloat); } }
自定义实现的模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class ObjectEvaluator implements TypeEvaluator { @Override public Object evaluate (float fraction, Object startValue, Object endValue) { .. return value; }
四. 实际的例子
我们先自定义一个TypeEvaluator:PointEvaluator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class PointEvaluator implements TypeEvaluator { @Override public Object evaluate (float fraction, Object startValue, Object endValue) { Point startPoint = (Point) startValue; Point endPoint = (Point) endValue; float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX()); float y = startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY()); return new Point(x,y); } }
自定义一个View:MyView,用来使用我们的估值器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 public class MyView extends View { public static final float RADIUS = 70f ; private Point currentPoint; private Paint paint; public MyView (Context context, @Nullable AttributeSet attrs) { super (context, attrs); paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.MAGENTA); } @Override protected void onDraw (Canvas canvas) { if (currentPoint == null ){ currentPoint = new Point(RADIUS,RADIUS); canvas.drawCircle(currentPoint.getX(),currentPoint.getY(),RADIUS,paint); Point startPoint = new Point(RADIUS,RADIUS); Point endPoint = new Point(700 ,700 ); ValueAnimator valueAnimator = ValueAnimator.ofObject(new PointEvaluator(),startPoint,endPoint); valueAnimator.setDuration(8000 ); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate (ValueAnimator animation) { currentPoint = (Point) animation.getAnimatedValue(); invalidate(); } }); valueAnimator.start(); }else { canvas.drawCircle(currentPoint.getX(),currentPoint.getY(),RADIUS,paint); } } }
每次动画更新的时候,就重绘视图,每次都是重绘的一个圆,只不过这个圆半径固定为RADIUS,圆心坐标是根据ValueAnimator监听更新时间中传递的值设置。