自定义插值器与Evaluator

  • 在视图动画中仅仅允许我们使用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()对应FloatEvaluator
    • ofInt()和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));    
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wjxbless

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值