天天看點

Android短文:了解插值器和估值器

Android短文:了解插值器和估值器

前言

最近想學的東西有點多...(潛台詞:一個也沒學~哈哈)待我學成之後,再出來“裝逼”...

今天整一篇“科普”向的文章,也是我自己一直傻傻分不清的内容:插值器、估值器。

正文

一、插值器Interpolator

什麼是插值器?根據時間流失的百分比 計算目前屬性改變的百分比。

使用場景:實作非線性運動的動畫效果

非線性運動:動畫改變的速率不是一成不變的,如加速 & 減速運動都屬于非線性運動

動畫是我們日常工作中不可缺少的一點。如果我們稍加注意就發發現預設的的動畫都是線性的,而一旦需求有所變動,比如需要一個加速度效果的動畫。此時插值器的作用就出現了。

TimeInterpolator

TimeInterpolator接口是屬性動畫中新增的,用于相容Interpolator接口,是以以後如果自定義插值器直接使用TimeInterpolator就可以了。

TimeInterpolator接口就一個方法.其中方法中的input表示時間流逝的百分比, teturn意味着我們自己算法下的屬性改變的百分比。

1. ​​public interface TimeInterpolator {​​
2. ​​    float getInterpolation(float input);​​
3. ​​}​​      

系統内置的插值器如下:

作用 資源ID 對應的Java類
預設的勻速 @android:anim/linear_interpolator LinearInterpolator
逐漸加速 @android:anim/accelerate_interpolator AccelerateInterpolator
先加速再減速 @android:anim/acceleratedecelerateinterpolator AccelerateDecelerateInterpolator
先退後再加速前進 @android:anim/anticipate_interpolator AnticipateInterpolator
周期運動 @android:anim/cycle_interpolator CycleInterpolator
動畫結束時抖動,類似皮球自由落體 DecelerateInterpolator
快速完成動畫,超出再回到結束點 @android:anim/overshoot_interpolator OvershootInterpolator
開始的時候向後甩一點,然後向前 @android:anim/anticipateovershootinterpolator AnticipateOvershootInterpolator

自定義插值器

V4包中增加了LookupTableInterpolator、FastOutLinearInInterpolator、FastOutSlowInInterpolator、LinearOutSlowInInterpolator如果系統内置的插值器不能滿足動畫需求可以自定義插值器

自定義插值器

  • 本質:根據動畫的進度(0%-100%)計算出目前屬性值改變的百分比。以怎樣的變化規律實作可以參考系統内置的插值器實作或者直接使用上面👆提到的網站生成
  • 具體使用:自定義插值器需要實作Interpolator / TimeInterpolator接口 & 複寫getInterpolation();ttmain中EaseCubicInterpolator就是自定義插值器,相對比較簡單
1. ​​//彈性插值器​​
2. ​​public class SpringInterpolator implements TimeInterpolator {​​
3. ​​    private float factor;//參數因子​​
4. ​​    public SpringInterpolator(float factor) {​​
5. ​​        this.factor = factor;​​
6. ​​    }​​
7. ​​    // 複寫getInterpolation()​​
8. ​​    @Override​​
9. ​​    public float getInterpolation(float input) {​​
10. ​​        return (float) (Math.pow(2, -10 * input) ​​
11. ​​        * Math.sin((input - factor / 4) ​​
12. ​​        * (2 * Math.PI) / factor) + 1);​​
13. ​​    }​​
14. ​​}​​      

二、估值器Evaluator

什麼是估值器:根據目前屬性改變的百分比來計算改變後的屬性值。

插值器決定屬性值随時間變化的規律;而具體變化屬性數值則交給估值器去計算。

TypeEvaluator

一個允許自定義估值器的類接口,實作 ​

​evaluator()​

​,其中:

  • fractio參數:動畫完成度,也就是插值器 ​

    ​getInterpolation()​

    ​的傳回,代表目前屬性值改變的百分比
  • startValue參數:動畫的初始值
  • endValue參數:動畫的結束值
  1. ​public interface TypeEvaluator<T> {​

  2. ​ public T evaluate(float fraction, T startValue, T endValue);​

  3. ​}​

系統内置的實作類

  • IntEvaluator Int類型估值器,傳回int類型的屬性改變
  • FloatEvaluator Float類型估值器,傳回Float類型屬性改變
  • ArgbEvaluator 顔色類型估值器,傳回16進制顔色值

自定義估值器

本質:根據插值器計算出目前屬性值改變的百分比 & 初始值 & 結束值 來計算此刻屬性變化的具體值;

自定義估值器很簡單,這裡舉個勻速估值器的例子:動畫進行了50%(初始值=100,結束值=200 ),那麼勻速插值器計算出了目前屬性值改變的百分比是50%,那麼估值器則負責計算目前屬性值 = 100 + (200-100)x50% = 150。

這裡随便整段代碼,大家感受一下就好了。如果需求上需要自定義估值器,方法實作需要自己根據業務去調整。

1. ​​// 實作TypeEvaluator接口​​
2. ​​public class PointEvaluator implements TypeEvaluator<Point> {​​
3. ​​    // 複寫evaluate()​​
4. ​​    // 在evaluate()裡寫入對象動畫過渡的邏輯​​
5. ​​    @Override​​
6. ​​    public Point evaluate(float fraction, Point startValue, Point endValue) {​​
7. ​​        // 根據fraction來計算目前動畫的x和y的值​​
8. ​​        int x = (int) (startValue.x + fraction * (endValue.x - startValue.x));​​
9. ​​        int y = (int) (startValue.y + fraction * (endValue.y - startValue.y));​​
10. ​​        // 将計算後的坐标封裝到一個新的Point對象中并傳回​​
11. ​​        return new Point(x, y);​​
12. ​​    }​​
13. ​​}​​      

三、總結

插值器和估值器關系

屬性動畫是對屬性做動畫,屬性要實作動畫。

  • 1、首先由插值器根據時間流逝的百分比計算出目前屬性值改變的百分比,然後由插值器将這個百分比傳回。這個時候插值器的工作就完成了。
比如 插值器 傳回的值是0.5,很顯然我們要的不是0.5
  • 插值器算好屬性變化百分比之後,由估值器根據目前屬性改變的百分比來計算改變後的屬性值,根據這個屬性值,我們就可以對View設定目前的屬性值了。

尾聲