動畫插值器Interpolation
插值器定義:
用於修改一個動畫過程中的速率,可以定義各種各樣的線性或非線性變化函式,比如勻速.加速.減速等。
說白了(也就是通俗的說):其實就是一個 時間的函式,用來 定義了動畫的變化律
系統的插值器:
在Android中所有的插值器都是Interpolator 的子類,下面是幾種插值器:
AccelerateDecelerateInterolator 先加速後減速,開始結束時慢,中間加速
AccelerateInterpolator 加速,開始時慢中間加速
DecelerateInterpolator 減速,開始時快然後減速
AnticipateInterpolator 反向 ,先向相反方向改變一段再加速播放
AnticipateOvershootInterpolator 反向加超越,先向相反方向改變,再加速播放,會超出目的值然後緩慢移動至目的值
BounceInterpolator 跳躍,快到目的值時值會跳躍,如目的值100,後面的值可能依次為85,77,70,80,90,100
CycleIinterpolator 迴圈,動畫迴圈一定次數,值的改變為一正弦函式:Math.sin(2 mCycles Math.PI * input)
LinearInterpolator 線性,線性均勻改變
OvershottInterpolator 超越,最後超出目的值然後緩慢改變到目的值
TimeInterpolator 一個介面,允許你自定義interpolator,以上幾個都是實現了這個介面
插值器的使用:
通過android:interpolator 屬性你可以引用不同的插值器,如:
1 2 3 |
<set android:interpolator="@android:anim/accelerate_interpolator"> ... </set> |
自定義插值器
(1)通過xml調整屬性
如果你對系統提供的插值器不滿意,我們可以建立一個插值器資源修改插值器的屬性,比如修改AnticipateInterpolator的加速速率,調整CycleInterpolator的迴圈次數等。為了完成這種需求,我們需要建立XML資原始檔,然後把其放於/res/anim下,然後再動畫元素中引用即可。我們先來看一下幾種常見的插值器可調整的屬性:
1 2 3 4 |
<?xml version="1.0" encoding="utf-8"?> <InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android" android:attribute_name="value" /> |
我們先來看一下幾種常見的插值器可調整的屬性:
android:factor 浮點值,加速速率,預設為1
android:tension 浮點值,起始點後退的張力、拉力數,預設為2
android:tension 同上 android:extraTension 浮點值,拉力的倍數,預設為1.5(2 * 1.5)
android:cycles int,迴圈的個數,預設為1
android:factor 浮點值,減速的速率,預設為1
浮點值,超出終點後的張力、拉力,預設為2
比如:res/anim/my_overshoot_interpolator.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?xml version="1.0" encoding="utf-8"?> <overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:tension="7.0"/> This animation XML will apply the interpolator: <scale xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@anim/my_overshoot_interpolator" android:fromXScale="1.0" android:toXScale="3.0" android:fromYScale="1.0" android:toYScale="3.0" android:pivotX="50%" android:pivotY="50%" android:duration="700" /> |
(2)繼承Interpolator介面完全自定義插值器
如果簡單的修改插值器的屬性值還不能夠滿足我們的需求,那麼就自己來通過實現Interpolator介面來定義自己的插值器了
因為上面所有的Interpolator都實現了Interpolator介面,這個介面定義了一個方法:float getInterpolation(float input);
此方法由系統呼叫,input代表動畫的時間,在0和1之間,也就是開始和結束之間。
線性(勻速)插值器定義如下:
1 2 3 |
public float getInterpolation(float input) { return input; } |
加速減速插值器定義如下:(其實也就是AccelerateDecelerateInterolator的原始碼)
1
2
3
|
public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}
|
解釋下這個getInterpolation(float input)方法
其作用就是把0到1的elapsed fraction變化對映到另一個interpolated fraction。傳入引數是正常執行動畫的時間點,返回值是使用者真正想要它執行的時間點。傳入引數是{0,1},返回值一般也是{0,1}。{0,1}表示整段動畫的過程。中間的0.2、0.3等小數表示在整個動畫(原本是勻速的)中的位置,其實就是一個比值。如果返回值是負數,會沿著相反的方向執行。如果返回的是大於1,會超出正方向執行。也就是說,動畫可能在你指定的值上下波動,大多數情況下是在指定值的範圍內。getInterpolation(float input)改變了預設動畫的時間點elapsed fraction,根據時間點interpolated fraction得到的是與預設時間點不同的屬性值,插值器的原理就是通過改變實際執行動畫的時間點,提前或延遲預設動畫的時間點來達到加速/減速的效果。動畫插值器目前都只是對動畫執行過程的時間進行修飾,並沒有對軌跡進行修飾。
簡單點解釋這個方法,就是當要執行input的時間時,通過Interpolator計算返回另外一個時間點,讓系統執行另外一個時間的動畫效果。經過動畫計算過程的第一步,會獲取一個已完成時間百分比elapsed fraction,也就是getInterpolation方法的引數input。