插值器与估值器

在属性动画中对值的计算需要插值器和估值器的参与,这样能产生更加丰富的动画

一、插值器

插值器其实是变化快慢的一个衡量标准,根据时间流逝的比例,来得出属性值变化的比例,具体来看一下插值器
的源码:
public interface TimeInterpolator {

/**
 * Maps a value representing the elapsed fraction of an animation to a value that represents
 * the interpolated fraction. This interpolated value is then multiplied by the change in
 * value of an animation to derive the animated value at the current elapsed animation time.
 *
 * @param input A value between 0 and 1.0 indicating our current point
 *        in the animation where 0 represents the start and 1.0 represents
 *        the end
 * @return The interpolation value. This value can be more than 1.0 for
 *         interpolators which overshoot their targets, or less than 0 for
 *         interpolators that undershoot their targets.
 */
float getInterpolation(float input);

}

这是一个接口,只有一个方法,input就是时间的流逝,返回的就是属性值变化的程度
其直接继承接口是Interpolator,这仍然是一个接口,Interpolator就有很多实现类了:匀速、加速、减速等等插值器

public class LinearInterpolator implements Interpolator {
    public LinearInterpolator() {
    }
    public LinearInterpolator(Context context, AttributeSet attrs) {
    }
    public float getInterpolation(float input) {
        return input;
    }
}


//AccelerateInterpolator
public float getInterpolation(float input) {
        if (mFactor == 1.0f) {
            return input * input;
        } else {
            return (float)Math.pow(input, mDoubleFactor);
        }
    }


//DecelerateInterpolator
public float getInterpolation(float input) {
        float result;
        if (mFactor == 1.0f) {
            result = (float)(1.0f - (1.0f - input) * (1.0f - input));
        } else {
            result = (float)(1.0f - Math.pow((1.0f - input), 2 * mFactor));
        }
        return result;
    }

从上面可以抽象出三个函数:

LinearInterpolator:result = input
AccelerateInterpolator:result = input^2
DecelerateInterpolator: result = 1-(1-input)^2

那么上面的result是如何反应变化速度的呢?
就是对input求导,也就是对时间求导,求导之后:

LinearInterpolator:result导数 = 1
AccelerateInterpolator:result导数 = 2 * input
DecelerateInterpolator: result导数 = 2*(1-input)

可以看出当input由0变成1时,LinearInterpolator导数不变,也就是匀速;AccelerateInterpolator导数变大,也就是
速度越来越快;DecelerateInterpolator导数越来越小,也就是速度越来越慢。

二、估值器

有了插值器得到的属性值的变化程度之后,就要算出具体的属性值了,比如从start变化到最终的end,某一时刻,
插值器得到变化程度为result,那么
属性值=start+(end-start)*result
让我们看一下源码中估值器都是如何计算属性值的:

public class IntEvaluator implements TypeEvaluator<Integer> {
    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
        int startInt = startValue;
        return (int)(startInt + fraction * (endValue - startInt));
    }
}
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);
    }
}

属性估值器唯一要实现的方法是evaluate方法,如上,源码中的估值器“估值”过程都是使用我们所讲的方法,那既然
方法都一样,为什么不使用同一个估值器呢?
原因是有些属性并不能直接按照上面的方法进行计算,比如:将View的背景色由红色变成蓝色,这种属性就不能简单
的使用上面的方法,因为这个属性并不是使用一个数值就能简单描述的,还好google工程师专门为颜色变化写了一个估值器

public class ArgbEvaluator implements TypeEvaluator {
    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))));
    }

}

仔细观察其实也是我们上面所说的方法,但是将argb各个数值进行计算,然后组合出来一个值。

总结

插值器就是反应属性变化的快慢,具体快慢的标准可以由插值器函数求导得到;估值器具体计算属性值,一般计算的方法就是
start+(end-start)*fraction

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值