1. 程式人生 > >動畫插值器Interpolation

動畫插值器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。