Android樣式的開發:View Animation篇

發表於2015-11-30

Android專案重構之路:架構篇

Android專案重構之路:介面篇

Android專案重構之路:實現篇

Android技術積累:開發規範

Android樣式的開發:shape篇

Android樣式的開發:selector篇

Android樣式的開發:layer-list篇

Android樣式的開發:drawable彙總篇

 

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,那就能實現淡出效果。示例程式碼如下:

 

將這動畫效果新增到View上也只需要一行程式碼:

 

如果需要重用這個動畫,也可以將其抽離出來。<alpha>標籤對應的動畫類為AlphaAnimation,父類為Animation,以上程式碼將AlphaAnimation抽離後的程式碼可以如下:

 

<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%表示底部邊緣

示例程式碼如下:

 

<scale>標籤對應的類為ScaleAnimation,父類也是Animation,新增到View上的用法和AlphaAnimation一樣,程式碼如下:

 

<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%的位置,即會移出父控制元件右邊緣的位置。

 

<translate>標籤對應的類為TranslateAnimation,父類也是Animation,新增到View上的程式碼如下:

 

<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本身中點的位置。

 

<rotate>標籤對應的類為RotateAnimation,父類也是Animation,新增到View上的程式碼如下:

 

<set>

<set>標籤可以將多個動畫組合起來,變成一個動畫集。比如想將一張圖片縮放的同時也做移動,這時候就要用<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檔案,程式碼如下:

 

接著,將其設定到要應用的動畫的android:interpolator屬性即可,程式碼如下:

 

寫在最後

檢視動畫的應用主要就這些了,比較簡單,當然也有其侷限性。比如只能應用於View,也只能做漸變、縮放、旋轉和移動,以及這些動畫的組合。下一篇再詳細講解屬性動畫,屬性動畫可以輕而易舉的做到許多檢視動畫做不到的事,比如說圖片的翻轉。

相關文章