前言
最近想學(xué)的東西有點多...(潛臺詞:一個也沒學(xué)~哈哈)待我學(xué)成之后,再出來“裝逼”...
今天整一篇“科普”向的文章,也是我自己一直傻傻分不清的內(nèi)容:插值器、估值器。
正文
一、插值器Interpolator
什么是插值器?
根據(jù)時間流失的百分比 計算當(dāng)前屬性改變的百分比。
使用場景:實現(xiàn)非線性運動的動畫效果
非線性運動:動畫改變的速率不是一成不變的,如加速 & 減速運動都屬于非線性運動
動畫是我們?nèi)粘9ぷ髦胁豢扇鄙俚囊稽c。如果我們稍加注意就發(fā)發(fā)現(xiàn)默認(rèn)的的動畫都是線性的,而一旦需求有所變動,比如需要一個加速度效果的動畫。此時插值器的作用就出現(xiàn)了。
TimeInterpolator
TimeInterpolator接口是屬性動畫中新增的,用于兼容Interpolator接口,因此以后如果自定義插值器直接使用TimeInterpolator就可以了。
TimeInterpolator接口就一個方法.其中方法中的input表示時間流逝的百分比, teturn意味著我們自己算法下的屬性改變的百分比。
public interface TimeInterpolator {
float getInterpolation(float input);
}
系統(tǒng)內(nèi)置的插值器如下:
| 作用 | 資源ID | 對應(yīng)的Java類 |
|---|---|---|
| 默認(rèn)的勻速 | @android:anim/linear_interpolator | LinearInterpolator |
| 逐漸加速 | @android:anim/accelerate_interpolator | AccelerateInterpolator |
| 先加速再減速 | @android:anim/accelerate_decelerate_interpolator | AccelerateDecelerateInterpolator |
| 先退后再加速前進 | @android:anim/anticipate_interpolator | AnticipateInterpolator |
| 周期運動 | @android:anim/cycle_interpolator | CycleInterpolator |
| 動畫結(jié)束時抖動,類似皮球自由落體 | DecelerateInterpolator | |
| 快速完成動畫,超出再回到結(jié)束點 | @android:anim/overshoot_interpolator | OvershootInterpolator |
| 開始的時候向后甩一點,然后向前 | @android:anim/anticipate_overshoot_interpolator | AnticipateOvershootInterpolator |
自定義插值器
V4包中增加了LookupTableInterpolator、FastOutLinearInInterpolator、FastOutSlowInInterpolator、LinearOutSlowInInterpolator如果系統(tǒng)內(nèi)置的插值器不能滿足動畫需求可以自定義插值器
自定義插值器
- 本質(zhì):根據(jù)動畫的進度(0%-100%)計算出當(dāng)前屬性值改變的百分比。以怎樣的變化規(guī)律實現(xiàn)可以參考系統(tǒng)內(nèi)置的插值器實現(xiàn)或者直接使用上面??提到的網(wǎng)站生成
- 具體使用:自定義插值器需要實現(xiàn)Interpolator / TimeInterpolator接口 & 復(fù)寫getInterpolation();ttmain中EaseCubicInterpolator就是自定義插值器,相對比較簡單
//彈性插值器
public class SpringInterpolator implements TimeInterpolator {
private float factor;//參數(shù)因子
public SpringInterpolator(float factor) {
this.factor = factor;
}
// 復(fù)寫getInterpolation()
@Override
public float getInterpolation(float input) {
return (float) (Math.pow(2, -10 * input)
* Math.sin((input - factor / 4)
* (2 * Math.PI) / factor) + 1);
}
}
二、估值器Evaluator
什么是估值器:根據(jù)當(dāng)前屬性改變的百分比來計算改變后的屬性值。
插值器決定屬性值隨時間變化的規(guī)律;而具體變化屬性數(shù)值則交給估值器去計算。
TypeEvaluator
一個允許自定義估值器的類接口,實現(xiàn)evaluator(),其中:
- fractio參數(shù):動畫完成度,也就是插值器
getInterpolation()的返回,代表當(dāng)前屬性值改變的百分比 - startValue參數(shù):動畫的初始值
- endValue參數(shù):動畫的結(jié)束值
public interface TypeEvaluator<T> {
public T evaluate(float fraction, T startValue, T endValue);
}
系統(tǒng)內(nèi)置的實現(xiàn)類
- IntEvaluator Int類型估值器,返回int類型的屬性改變
- FloatEvaluator Float類型估值器,返回Float類型屬性改變
- ArgbEvaluator 顏色類型估值器,返回16進制顏色值
自定義估值器
本質(zhì):根據(jù)插值器計算出當(dāng)前屬性值改變的百分比 & 初始值 & 結(jié)束值 來計算此刻屬性變化的具體值;
自定義估值器很簡單,這里舉個勻速估值器的例子:動畫進行了50%(初始值=100,結(jié)束值=200 ),那么勻速插值器計算出了當(dāng)前屬性值改變的百分比是50%,那么估值器則負(fù)責(zé)計算當(dāng)前屬性值 = 100 + (200-100)x50% = 150。
這里隨便整段代碼,大家感受一下就好了。如果需求上需要自定義估值器,方法實現(xiàn)需要自己根據(jù)業(yè)務(wù)去調(diào)整。
// 實現(xiàn)TypeEvaluator接口
public class PointEvaluator implements TypeEvaluator<Point> {
// 復(fù)寫evaluate()
// 在evaluate()里寫入對象動畫過渡的邏輯
@Override
public Point evaluate(float fraction, Point startValue, Point endValue) {
// 根據(jù)fraction來計算當(dāng)前動畫的x和y的值
int x = (int) (startValue.x + fraction * (endValue.x - startValue.x));
int y = (int) (startValue.y + fraction * (endValue.y - startValue.y));
// 將計算后的坐標(biāo)封裝到一個新的Point對象中并返回
return new Point(x, y);
}
}
三、總結(jié)
插值器和估值器關(guān)系
屬性動畫是對屬性做動畫,屬性要實現(xiàn)動畫。
- 1、首先由插值器根據(jù)時間流逝的百分比計算出當(dāng)前屬性值改變的百分比,然后由插值器將這個百分比返回。這個時候插值器的工作就完成了。
比如 插值器 返回的值是0.5,很顯然我們要的不是0.5
- 插值器算好屬性變化百分比之后,由估值器根據(jù)當(dāng)前屬性改變的百分比來計算改變后的屬性值,根據(jù)這個屬性值,我們就可以對View設(shè)置當(dāng)前的屬性值了。
尾聲
OK,關(guān)于插值器和估值器我想聊的就是這么多,很簡單很簡單的內(nèi)容。就當(dāng)日常查缺補漏,碎片時間下的一點點提升吧~~