自定义插值器与Evaluator

    xiaoxiao2023-10-16  25

    在视图动画中仅仅允许我们使用setInterpolator()函数来设置插值器,但是对于Animator来说,不仅可以设置插值器,还可以设置Evalator(差值器)比如刚才我们定义的ofInt(0,400)那么他的移动速度是通过什么来设置的呢,插值器就是用来控制动画的区间值如何被计算出来的系统自带的匀速插值器: public class LinearInterpolator implements Interpolator{ public LinearInterpolator(){ } public LinearInterpolator(Context context, AttributeSet attrs0{ } public float getInterpolation(float input){ return input; } } //实现了Interpolator接口, 继承了TimeInterpolator public interface Interpolator extends TimeInterpolator{ } TimeInterpolator: public interface TImeInterpolator{ //input表示当前动画的进度。取0时表示动画开始,取1时表示动画结束 //返回值表示当前想要显示的进度,超过1表示已经超过目标值,小于0表示小于开始位置 //动画随着设定的时长均匀增加,返回值的对应的是使用ofInt()还是ofFloat() float getInterpolation(float input); } 理解ofInt(): ofint(100,400); curValue = 100 + (400-100)*进度 所以说现实的进度就是当前的位置
    注意:input的值与设定的距离没有任何关系,只与时间有关,随着时间的推移进度也就自然的增加,input参数表示来了当前的动画的进度,返回值表示当前的动画的数值进度。
    插值器进度源码:
    LinearInterpolator 匀速: public class LinearInterpolator implements Interpolator{ public float getInterpolator(float input){ return input; } } //发现直接将input返回,也就是说时间和进度是同步变化的,多以就是匀速变化 AccelerateDecelerateInterpolator 先加速后减速: public float getInterpolation(float input) {    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; } 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; } BounceInterpolator 弹跳: public float getInterpolation(float t) {    // _b(t) = t * t * 8    // bs(t) = _b(t) for t < 0.3535    // bs(t) = _b(t - 0.54719) + 0.7 for t < 0.7408    // bs(t) = _b(t - 0.8526) + 0.9 for t < 0.9644    // bs(t) = _b(t - 1.0435) + 0.95 for t <= 1.0    // b(t) = bs(t * 1.1226)    t *= 1.1226f;    if (t < 0.3535f) return bounce(t);    else if (t < 0.7408f) return bounce(t - 0.54719f) + 0.7f;    else if (t < 0.9644f) return bounce(t - 0.8526f) + 0.9f;    else return bounce(t - 1.0435f) + 0.95f; } AnticipateInterpolator 反向初始: public float getInterpolation(float t) {    // a(t) = t * t * ((tension + 1) * t - tension)    return t * t * ((mTension + 1) * t - mTension); } OvershootInterpolator 前向结束: public float getInterpolation(float t) {    // _o(t) = t * t * ((tension + 1) * t + tension)    // o(t) = _o(t - 1) + 1    t -= 1.0f;    return t * t * ((mTension + 1) * t + mTension) + 1.0f; } AnticipateOvershootInterpolator 上述两者结合: public float getInterpolation(float t) {    // a(t, s) = t * t * ((s + 1) * t - s)    // o(t, s) = t * t * ((s + 1) * t + s)    // f(t) = 0.5 * a(t * 2, tension * extraTension), when t < 0.5    // f(t) = 0.5 * (o(t * 2 - 2, tension * extraTension) + 2), when t <= 1.0    if (t < 0.5f) return 0.5f * a(t * 2.0f, mTension);    else return 0.5f * (o(t * 2.0f - 2.0f, mTension) + 2.0f); } CycleInterpolator 循环插值器 : public float getInterpolation(float input) {    return (float)(Math.sin(2 * mCycles * Math.PI * input)); } 看了上述的插值器的getInterpolator函数后, 自定义一个插值器: public class MyInterpolator implements TimeInterpolator {    @Override    public float getInterpolation(float input) {        //反向插值器        return 1-input;    } } Evaluator: 数值转换器,负责将插值器返回的小数表示的进度的,转化为数值表示的位置ofInt()对应IntEvaluator, ofFloat()对应FloatEvaluatorofInt()和ofFloat()都有系统默认的Evaluator和Interpolator供使用,分别默认的就是上述的两个函数 来看一下IntEvaluator的源码实现: public class IntEvaluator implements TypeEvaluator<Integer> {    //fraction就是其中的插值器的返回值,表示当前动画的数值进度,百分小数表示 //startValue和endValue分别表示ofInt()中的两个参数, //返回值就是curValue的具体的数值 //计算方式:eg: 100 + (400-100)*进度 public Integer evaluate(float fraction, Integer startValue, Integer endValue) {        int startInt = startValue;        return (int)(startInt + fraction * (endValue - startInt));    } } 实现一个Evaluator: public class MyEvaluator implements TypeEvaluator<Integer> {    @Override    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {        int startInt = startValue;        //在实际的基础上加200        return (int)(200  + startInt + fraction*(endValue-startInt));    } }
    总结:我们既可以 通过重写插值器的getInterpolator()函数来改变数值及进度的位置,也可以通过重写evaluate()函数来改变数值位置
    反向动画(上述通过getInterpolatotr实现): public class ReserveEvaluator implements TypeEvaluator<Integer> {    @Override    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {        int startInt = startValue;        //实现反向动画        return (int)(endValue - fraction * (endValue-startInt));    } }
    最新回复(0)