Android动画全篇系列(五)——估值器

一、估值器(TypeEvaluator)介绍

如果要为 Android 系统无法识别的类型添加动画效果,则可以通过实现 TypeEvaluator 接口来创建您自己的评估程序。Android 系统可以识别的类型为 int、float 或颜色,分别由 IntEvaluator、FloatEvaluator 和 ArgbEvaluator 类型评估程序提供支持。——亲爸爸谷歌

估值器允许开发者在任意属性类型上创建动画,能够为动画系统无法自动理解或使用的类型自定义估值器。——API文档

首先要明白:插值器和估值器没有半毛钱关系!但是有一毛钱关系!!!

插值器帮我们完成了在动画开始至结束的0到1的某个时刻,值的变化规律。
而估值器则是通过插值器的变化规律,帮我们定义值的类型和值的具体范围。

二、详解

如果你还是对估值器的概念一脸懵逼的话,不妨以例子作为切入点,我们从例子慢慢分析。

在上一章中,我们用代码初始化ObjectAnimation的时候,有利用到系统默认提供的FloatEvaluator

val objectAnimator = 
ObjectAnimator.ofObject(viewHolder,"PropertyName",FloatEvaluator(),0f,1f)

这时候,我们定义的值的类型时Float。我们直接看看FloatEvaluator的源码,只有一个方法:

public Float evaluate(float fraction, Number startValue, Number endValue) {
    float startFloat = startValue.floatValue();
    return startFloat + fraction * (endValue.floatValue() - startFloat);
}
  • startValue 是指初始值
  • endValue 是指最终值
  • fraction 是指从startValueendValue的动画的进度,这个值是从0到1的float值。其变化的速率和插值器是有关联的假设插值器使用的是LinearInterpolator线性插值器,那么fraction的变化也是线性的!
  • return 生成的具体值!在上个Demo中,就是直接操控View的透明度的值。

1、我们知道,一个动画设置value的时候是可以设置多个的,比如说设置了三个值:(0f,1f,2f)

那么估值器在这段时间内会一值被调用 evaluate() 方法,fraction始终是从0到1的变化,而startValueendValue会以下面的方式变化:

startValueendValue
01.0
…………
01.0
1.02.0
…………
1.02.0
动画结束动画结束

2、需要注意的是:因为估值器返回的值会直接影响显示的效果,如果把fraction看作是xstartValueendValue是常量,其返回值y必须满足与x*(endValue - startValue) 构成的等式为一元一次方程。

在数学上,我们叫做线性关系。

否则你估值器双倍工资,把插值器的活也干了。

三、自定义估值器

在一般情况下,我们为属性设置一些值,例如设置View的透明度,我们传的是Float类型的,系统为我们提供了FloatEvaluator来帮助我们计算生成的值。

那如果我们传的是两个点(Point/PointF)呢?来计算实现View移动在两个点之间的位置。

好在系统也为我们提供了PointFEvaluator
虚惊
那么总有一天你会遇到疑难杂症吧!只能来自定义估值器了。

1、以FloatEvaluator作为初始研究对象

我们把目光再次放到这个明星类身上:

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

这就是FloatEvaluator 类的全部代码,仅仅4行。

从这里我们就能够得出自定义插值器的所有相关的点。

  1. 创建一个类并且实现TypeEvaluator接口。
  2. 定义好TypeEvaluator的泛型,这个类就是你所传的值的类型。例如你在创建某个ObjectAnimator的时候:
    ObjectAnimator.ofObject(view,"PropertyName",XXEvaluator(),obj1,obj2)
    那么这个泛型的类型就是obj1obj2的类型了。
  3. evaluate() 方法中实现那个传说中的线性关系
2、以PointFEvaluator作为代入研究对象

其实在系统中已经有了这个PointFEvaluator这个类,那么现在假设我们自己也来写这样一个类(自定义估值器的例子少见啊)。

OK,话不多说,直接开撸:

public class PointFEvaluator : TypeEvaluator<PointF>

因为我们要传入两个点作为值,所以泛型的类型就定义为PointF

  1. 重写 evaluate() 方法:
override fun evaluate(fraction: Float, startValue: PointF, endValue: PointF): PointF {
	//两个点之间如何计算呢?当然是分两步,
	//1、计算 x 之间的值 2、计算 y 之间的值
	//最后拿到生成的 x 和 y 组成一个新的点
	val x = startValue.x + (fraction * (endValue.x - startValue.x))
	val y = startValue.y + (fraction * (endValue.y - startValue.y));   
	
	return PointF(x,y)          
}

到这里就已经完成了自定义估值器了(实际上的PointFEvaluator的代码会多一小点点性能上的优化)。具体效果就不展示了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值