TypeEvaluator简介
Android提供了以下几个简单的Evalutor实现类:
- IntEvaluator:属性的值类型为int
- FloatEvaluator:属性的值类型为float
- ArgbEvaluator:属性的值类型为十六进制颜色值
TypeEvaluator:一个接口,可以通过实现该接口自定义Evaluator。
TypeEvaluator的实现过程:
首先根据动画【已进行的时间】跟动画【总时间】的比计算出一个时间因子(0~1,即evalute()中的fraction参数,这个值是自动计算得到的)
然后根据【TimeInterpolator】得到出另一个算法因子
TypeEvaluator通过这【两个】因子计算出属性值并将其【传给】我们定义的泛型对象
最后在我们监听动画的绘制过程中,将泛型对象中保存的值【取出】并用于【更改】目标对象的属性
自定义TypeEvaluator时传入的泛型可以根据自己的需求,自己设计个Bean。
只要
evaluate中的函数能够满足:当fraction=0时返回值为startValue,并且当fraction=1时返回值为endValue,就是一个比较合理的函数。
TypeEvaluator 接口源码
/**
* Interface for use with the ValueAnimator#setEvaluator(TypeEvaluator) function. Evaluators
* allow developers to create animations on arbitrary任意的 property types, by allowing them to supply
* custom evaluators for types that are not automatically understood and used by the animation system.
*/
public interface TypeEvaluator<T> {
/**
* This function returns the result of linearly interpolating the start and end values, with fraction representing
* the proportion比例 between the start and end values. The calculation is a simple parametric参数
* calculation: result = x0 + t * (x1 - x0), where "x0" is startValue, "x1" is endValue, and "t" is fraction.
* @param fraction The fraction from the starting to the ending values
* @return A linear interpolation between the start and end values, given the fraction parameter.
*/
public T evaluate(float fraction, T startValue, T endValue);
}
IntEvaluator 源码
/** This evaluator can be used to perform type interpolation between int values. */
public class IntEvaluator implements TypeEvaluator<Integer> {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
return (int)(startValue + fraction * (endValue - startValue));
}
}
FloatEvaluator 源码
public Float evaluate(float fraction, Number startValue, Number endValue) {
return startValue.floatValue() + fraction * (endValue.floatValue() - startValue.floatValue());
}
ArgbEvaluator 源码
/** integer values that represent ARGB colors. */
public class ArgbEvaluator implements TypeEvaluator {
/**
* This function returns the calculated in-between value for a color given integers that represent
* the start and end values in the four bytes of the 32-bit int. Each channel is separately单独的
* linearly interpolated and the resulting calculated values are recombined into the return value.
* @param fraction The fraction from the starting to the ending values
* @param startValue A 32-bit int value representing colors in the separate bytes of the parameter
* @param endValue A 32-bit int value representing colors in the separate bytes of the parameter
* @return A value that is calculated to be the linearly interpolated result, derived by separating
* the start and end values into separate color channels and interpolating each one separately,
* recombining the resulting values in the same way.
*/
public Object evaluate(float fraction, Object startValue, Object endValue) {
int startInt = (Integer) startValue;
int startA = (startInt >> 24) & 0xff;
int startR = (startInt >> 16) & 0xff;
int startG = (startInt >> 8) & 0xff;
int startB = startInt & 0xff;
int endInt = (Integer) endValue;
int endA = (endInt >> 24) & 0xff;
int endR = (endInt >> 16) & 0xff;
int endG = (endInt >> 8) & 0xff;
int endB = endInt & 0xff;
return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
(int)((startR + (int)(fraction * (endR - startR))) << 16) |
(int)((startG + (int)(fraction * (endG - startG))) << 8) |
(int)((startB + (int)(fraction * (endB - startB))));
}
}
自定义TypeEvaluator实现抛物线效果
自定义TypeEvaluator时传入的泛型可以根据自己的需求,自己设计个Bean。
为了以不同的函数分别设置x和y的位置,我们自定义的TypeEvaluator传入的泛型为PointF对象,每次根据当前时间返回一个PointF对象,PointF中的x、y代表View当前的位置,然后在监听动画绘制过程时更新UI。
自定义TypeEvaluator
public class PointFEvaluator implements TypeEvaluator<PointF> {
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
//只要能保证:当fraction=0时返回值为startValue,并且当fraction=1时返回值为endValue,就是一个比较合理的函数
PointF pointF = new PointF();
pointF.x = startValue.x + fraction * (endValue.x - startValue.x);// x方向匀速移动
pointF.y = startValue.y + fraction * fraction * (endValue.y - startValue.y);// y方向抛物线加速移动
return pointF;
}
}
在Activity中的使用
// 自定义TypeEvaluator实现抛物线动画效果
public class TypeEvaluatorActivity extends Activity {
private ImageView iv_src;
private boolean b = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);//取消标题栏
Bitmap bitmap = Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setDither(true);
canvas.drawCircle(10, 10, 10, paint);
iv_src = new ImageView(this);
iv_src.setImageBitmap(bitmap);
setContentView(iv_src, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
b = !b;
Point point = new Point();
((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(point);
ValueAnimator animator = new ValueAnimator().setDuration(1000);
//通过new创建的ValueAnimator要明确的setObjectValues和setEvaluator,并且一定要先setObjectValues,再setEvaluator
if (b) animator.setObjectValues(new PointF(0, 0), new PointF(point.x - iv_src.getWidth(), point.y - iv_src.getHeight()));
else animator.setObjectValues(new PointF(0, point.y - iv_src.getHeight()), new PointF(point.x - iv_src.getWidth(), 0));
animator.setEvaluator(new PointFEvaluator());//PointFEvaluator为自定义的估值器,其实就是用来封装你需要的数据用的
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF point = (PointF) animation.getAnimatedValue();
iv_src.setX(point.x);
iv_src.setY(point.y);
}
});
animator.start();
}
return super.onTouchEvent(event);
}
}