drawable彙總篇講過兩個動畫,animation-list定義幀動畫,animated-rotate定義旋轉動畫,這兩個屬於drawable動畫。除了drawable動畫,Android框架還提供了另外兩種動畫體系:檢視動畫(View Animation)和屬性動畫(Property Animation)。檢視動畫比較簡單,只能應用於各種View,可以做一些位置、大小、旋轉和透明度的簡單轉變。屬性動畫則是在android 3.0引入的動畫體系,提供了更多特性和靈活性,也可以應用於任何物件,而不只是View。本篇先講檢視動畫。
檢視動畫可以通過xml檔案定義,xml檔案放於res/anim/目錄下,根元素可以為:<alpha>, <scale>,<translate>, <rotate>, 或者<set>。其中,<set>標籤定義的是動畫集,它可以包含多個其他標籤,也可以巢狀<set>標籤。預設情況下,所有動畫會同時播放;如果想按順序播放,則需要指定startOffset屬性;另外,還可以通過設定interpolator改變動畫變化的速率,比如勻速、加速。
<alpha>
<alpha>可以實現透明度漸變的動畫效果,也就是淡入淡出的效果,可通過設定下面三個屬性來設定淡入或淡出效果:
- android:duration 動畫從開始到結束持續的時長,單位為毫秒
- android:fromAlpha 動畫開始時的透明度,0.0為全透明,1.0為不透明,預設為1.0
- android:toAlpha 動畫結束時的透明度,0.0為全透明,1.0為不透明,預設為1.0
當設定開始時透明度為0.0,結束時為1.0,就能實現淡入效果;相反,當設定開始時透明度為1.0,結束時為0.0,那就能實現淡出效果。示例程式碼如下:
1 2 3 4 5 6 |
<!-- res/anim/fade_in.xml --> <?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:fromAlpha="0.0" android:toAlpha="1.0" /> |
將這動畫效果新增到View上也只需要一行程式碼:
1 |
view.startAnimation(AnimationUtils.loadAnimation(this, R.anim.fade_in)); |
如果需要重用這個動畫,也可以將其抽離出來。<alpha>標籤對應的動畫類為AlphaAnimation,父類為Animation,以上程式碼將AlphaAnimation抽離後的程式碼可以如下:
1 2 |
AlphaAnimation fadeInAnimation = (AlphaAnimation) AnimationUtils.loadAnimation(this, R.anim.fade_in); view.startAnimation(fadeInAnimation); |
<scale>
<scale>可以實現縮放的動畫效果,主要的屬性如下:
- android:duration 動畫從開始到結束持續的時長,單位為毫秒
- android:fromXScale 動畫開始時X座標上的縮放尺寸
- android:toXScale 動畫結束時X座標上的縮放尺寸
- android:fromYScale 動畫開始時Y座標上的縮放尺寸
- android:toYScale 動畫結束時Y座標上的縮放尺寸
PS:以上四個屬性,0.0表示縮放到沒有,1.0表示正常無縮放,小於1.0表示收縮,大於1.0表示放大 - android:pivotX 縮放時的固定不變的X座標,一般用百分比表示,0%表示左邊緣,100%表示右邊緣
- android:pivotY 縮放時的固定不變的Y座標,一般用百分比表示,0%表示頂部邊緣,100%表示底部邊緣
示例程式碼如下:
1 2 3 4 5 6 7 8 9 10 |
<!-- res/anim/zoom_out.xml --> <?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:fromXScale="1.0" android:fromYScale="1.0" android:pivotX="0%" android:pivotY="100%" android:toXScale="1.5" android:toYScale="1.5" /> |
<scale>標籤對應的類為ScaleAnimation,父類也是Animation,新增到View上的用法和AlphaAnimation一樣,程式碼如下:
1 2 |
ScaleAnimation zoomOutAnimation = (ScaleAnimation) AnimationUtils.loadAnimation(this, R.anim.zoom_out); view.startAnimation(zoomOutAnimation); |
<translate>
<translate>可以實現位置移動的動畫效果,可以是垂直方向的移動,也可以是水平方向的移動。座標的值可以有三種格式:從-100到100,以”%”結束,表示相對於View本身的百分比位置;如果以”%p”結束,表示相對於View的父View的百分比位置;如果沒有任何字尾,表示相對於View本身具體的畫素值。主要的屬性如下:
- android:duration 動畫從開始到結束持續的時長,單位為毫秒
- android:fromXDelta 起始位置的X座標的偏移量
- android:toXDelta 結束位置的X座標的偏移量
- android:fromYDelta 起始位置的Y座標的偏移量
- android:toYDelta 結束位置的Y座標的偏移量
看示例吧,以下程式碼實現的是從左到右的移動效果,起始位置為相對於控制元件本身-100%的位置,即在控制元件左邊,與控制元件本身寬度一致的位置;結束位置為相對於父控制元件100%的位置,即會移出父控制元件右邊緣的位置。
1 2 3 4 5 6 7 8 |
<!-- res/anim/move_left_to_right.xml --> <?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromXDelta="-100%" android:fromYDelta="0" android:toXDelta="100%p" android:toYDelta="0" /> |
<translate>標籤對應的類為TranslateAnimation,父類也是Animation,新增到View上的程式碼如下:
1 2 |
TranslateAnimation moveAnimation = (TranslateAnimation) AnimationUtils.loadAnimation(this, R.anim.move_left_to_right); view.startAnimation(moveAnimation); |
<rotate>
<rotate>可以實現旋轉的動畫效果,主要的屬性如下:
- android:duration 動畫從開始到結束持續的時長,單位為毫秒
- android:fromDegrees 旋轉開始的角度
- android:toDegrees 旋轉結束的角度
- android:pivotX 旋轉中心點的X座標,純數字表示相對於View本身左邊緣的畫素偏移量;帶”%”字尾時表示相對於View本身左邊緣的百分比偏移量;帶”%p”字尾時表示相對於父View左邊緣的百分比偏移量
- android:pivotY 旋轉中心點的Y座標,純數字表示相對於View本身頂部邊緣的畫素偏移量;帶”%”字尾時表示相對於View本身頂部邊緣的百分比偏移量;帶”%p”字尾時表示相對於父View頂部邊緣的百分比偏移量
以下示例程式碼旋轉角度從0到360,即旋轉了一圈,旋轉的中心點都設為了50%,即是View本身中點的位置。
1 2 3 4 5 6 7 8 |
<!-- res/anim/rotate_one.xml --> <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" /> |
<rotate>標籤對應的類為RotateAnimation,父類也是Animation,新增到View上的程式碼如下:
1 2 |
RotateAnimation rotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(this, R.anim.rotate_one); view.startAnimation(rotateAnimation); |
<set>
<set>標籤可以將多個動畫組合起來,變成一個動畫集。比如想將一張圖片縮放的同時也做移動,這時候就要用<set>標籤組合縮放動畫和移動動畫了。示例程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!-- res/anim/move_and_scale.xml --> <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000"> <translate android:fromXDelta="0" android:fromYDelta="0" android:toXDelta="200%" android:toYDelta="0" /> <scale android:fromXScale="1.0" android:fromYScale="1.0" android:pivotX="0%" android:pivotY="100%" android:toXScale="1.5" android:toYScale="1.5" /> </set> |
以上程式碼實現的動畫效果為向右移動的同時也同步放大。<set>標籤在檢視動畫中除了可以組合<alpha>,<scale>, <translate>, <rotate>這四種標籤,也可以巢狀其他<set>標籤。另外,<set>標籤可巢狀的標籤元素並不只有這幾個,後面談到屬性動畫時會再講其他的標籤及用法。
通用屬性
仔細觀察不難發現,以上五個標籤都有android:duration屬性,這是一個通用的屬性,而除了android:duration,還有其他的通用屬性,接下來看看都有哪些通用屬性以及相應的用法:
- android:duration 動畫從開始到結束持續的時長,單位為毫秒
- android:detachWallpaper 設定是否在桌布上執行,只對設定了桌布背景的視窗動畫(window animation)有效。設為true,則動畫只在視窗執行,桌布背景保持不變
- android:fillAfter 設定為true時,動畫執行完後,View會停留在動畫的最後一幀;預設為false;如果是動畫集,需在<set>標籤中設定該屬性才有效
- android:fillBefore 設定為true時,動畫執行完後,View回到動畫執行前的狀態,預設即為true
- android:fillEnabled 設定為true時,android:fillBefore的值才有效,否則android:fillBefore會被忽略
- android:repeatCount 設定動畫重複執行的次數,預設為0,即不重複;可設為-1或infinite,表示無限重複
- android:repeatMode 設定動畫重複執行的模式,可設為以下兩個值其中之一:
- restart 動畫重複執行時從起點開始,預設為該值
- reverse 動畫會反方向執行
- android:startOffset 設定動畫執行之前的等待時長,毫秒為單位;重複執行時,每次執行前同樣也會等待一段時間
- android:zAdjustment 表示被設定動畫的內容在動畫執行時在Z軸上的位置,取值為以下三個值之一:
- normal 預設值,保持內容在Z軸上的位置不變
- top 保持在Z周最上層
- bottom 保持在Z軸最下層
- android:interpolator 設定動畫速率的變化,比如加速、減速、勻速等,需要指定Interpolator資源,後面再詳細講解
PS:<set>標籤還有個android:shareInterpolator屬性,設定為true時則可將interpolator應用到所有子元素中
Interpolator
通過interpolator可以定義動畫速率變化的方式,比如加速、減速、勻速等,每種interpolator都是Interpolator 類的子類,Android系統已經實現了多種interpolator,對應也提供了公共的資源ID,如下表:
Interpolator class | Resource ID | Description |
---|---|---|
AccelerateDecelerateInterpolator | @android:anim/accelerate_decelerate_interpolator | 在動畫開始與結束時速率改變比較慢,在中間的時候加速 |
AccelerateInterpolator | @android:anim/accelerate_interpolator | 在動畫開始時速率改變比較慢,然後開始加速 |
AnticipateInterpolator | @android:anim/anticipate_interpolator | 動畫開始的時候向後然後往前拋 |
AnticipateOvershootInterpolator | @android:anim/anticipate_overshoot_interpolator | 動畫開始的時候向後然後向前拋,會拋超過目標值後再返回到最後的值 |
BounceInterpolator | @android:anim/bounce_interpolator | 動畫結束的時候會彈跳 |
CycleInterpolator | @android:anim/bounce_interpolator | 動畫迴圈做週期運動,速率改變沿著正弦曲線 |
DecelerateInterpolator | @android:anim/decelerate_interpolator | 在動畫開始時速率改變比較快,然後開始減速 |
LinearInterpolator | @android:anim/decelerate_interpolator | 動畫勻速播放 |
OvershootInterpolator | @android:anim/overshoot_interpolator | 動畫向前拋,會拋超過最後值,然後再返回 |
如果系統提供的以上Interpolator還不符合你的效果,也可以自定義。自定義的方式有兩種,一種是通過繼承 Interpolator 父類或其子類;另一種是通過自定義的xml檔案,可以更改上表中Interpolator的屬性。自定義的xml檔案需存放於res/anim/目錄下,根標籤與上表相應的有九種如下:
- <accelerateDecelerateInterpolator> 在動畫開始與結束時速率改變比較慢,在中間的時候加速。沒有可更改設定的屬性,所以設定的效果和系統提供的一樣
- <accelerateInterpolator> 在動畫開始時速率改變比較慢,然後開始加速。有一個屬性可以設定加速的速率
- android:factor 浮點值,加速的速率,預設為1
- <anticipateInterpolator> 動畫開始的時候向後然後往前拋。有一個屬性設定向後拉的值
- android:tension 浮點值,向後的拉力,預設為2,當設為0時,則不會有向後的動畫了
- <anticipateOvershootInterpolator> 動畫開始的時候向後然後向前拋,會拋超過目標值後再返回到最後的值。可設定兩個屬性
- android:tension 浮點值,向後的拉力,預設為2,當設為0時,則不會有向後的動畫了
- android:extraTension 浮點值,拉力的倍數,預設為1.5(2*1.5),當設為0時,則不會有拉力了
- <bounceInterpolator> 動畫結束的時候會彈跳。沒有可更改設定的屬性
- <cycleInterpolator> 動畫迴圈做週期運動,速率改變沿著正弦曲線。有一個屬性設定迴圈次數
- android:cycles 整數值,迴圈的次數,預設為1
- <decelerateInterpolator> 在動畫開始時速率改變比較快,然後開始減速。有一個屬性設定減速的速率
- android:factor 浮點值,減速的速率,預設為1
- <linearInterpolator> 動畫勻速播放。沒有可更改設定的屬性
- <overshootInterpolator> 動畫向前拋,會拋超過最後值,然後再返回。有一個屬性
- android:tension 浮點值,超出終點後的拉力,預設為2
具體用法,就舉個示例吧,先定義個interpolator的xml檔案,程式碼如下:
1 2 3 4 5 6 |
<!-- res/anim/my_interpolator.xml --> <?xml version="1.0" encoding="utf-8"?> <anticipateOvershootInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:tension="3" android:extraTension="2" /> |
接著,將其設定到要應用的動畫的android:interpolator屬性即可,程式碼如下:
1 2 3 4 5 6 7 8 9 |
<!-- res/anim/rotate_one.xml --> <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:interpolator="@anim/my_interpolator" /> |
寫在最後
檢視動畫的應用主要就這些了,比較簡單,當然也有其侷限性。比如只能應用於View,也只能做漸變、縮放、旋轉和移動,以及這些動畫的組合。下一篇再詳細講解屬性動畫,屬性動畫可以輕而易舉的做到許多檢視動畫做不到的事,比如說圖片的翻轉。