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);
    }

}


最新文章

  1. 那些年我们一起过的JS闭包,作用域,this,让我们一起划上完美的句号。
  2. C#字符串处理(String与StringBuilder)
  3. C#之参数线程
  4. 搭建SpringMVC+MyBatis开发框架二
  5. VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)
  6. PyQt4学习笔记2:事件和信号
  7. CentOS 如何将.deb 文件 转换.rpm
  8. lc面试准备:Regular Expression Matching
  9. close函数
  10. Failed to load resource: the server responded with a status of 413 (Request Entity Too Large)
  11. asp.net错误.在应用程序级别之外使用注册为 allowDefinition=&#39;MachineToApplication&#39; 的节是错
  12. 总结一些php的面试题
  13. 难受的ESlint语法检测
  14. Python3练习题 018:打印星号菱形
  15. 玩转EhCache之最简单的缓存框架
  16. 网络编程-day1
  17. Python+Selenium学习--控制浏览器控制条
  18. [administrative][lvm] lvm 分区修改
  19. 【leetcode】27-RemoveElement
  20. python------面向对象介绍之经典类与新式类的继承顺序

热门文章

  1. centos7 时间同步
  2. oracle 内连接、外连接、自然连接、交叉连接练习
  3. Django学习笔记-2018.12.08
  4. PHP实现插入排序
  5. 洛谷P2147 [SDOI2008] 洞穴勘探 [LCT]
  6. 实验 Unity Linear Color Space 发现结果不符合预期
  7. Linux命令之usermod
  8. 苹果无sim卡激活
  9. Entity Framework(实体框架 EF)
  10. [HNOI2018]道路 --- 树形DP