1. 程式人生 > >Android應用開發:動畫開發——XML動畫

Android應用開發:動畫開發——XML動畫

引言

當今,Android、IOS二分天下,什麼Tizen、COS blabla的均為螻蟻,一看就知道是為打發領導或為花研發資金產出的產品,根本不是為了贏得市場,為的只是博得領導一笑而已,完全可以忽視。而Android開發又因為開發語言以Java為主,入門門檻極低導致基本上是個程式設計師,泡兩天EOE,或Android Developer Training都可以過來說“哥會開發Android app了!”,那麼什麼才能將你的App脫穎而出呢?準確的使用者痛點、良好的資料結構、簡單易用的互動流程、大方前衛的設計風格等等等等都是必要的,而對於使用者來說,最直觀、最直接、最能被打動的就是介面,本片部落格就來講述一下Android介面開發中不可小覷的動畫開發,初步決定要分為三篇部落格進行詳解,分別是xml動畫、程式碼動畫、插值器。本篇作為開篇,就來講述一下xml動畫的開發。

定義

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:pivotX="50%p"
        android:pivotY="50%p"
        android:fromXScale="1" android:toXScale=".85"
        android:fromYScale="1" android:toYScale=".85"
        android:duration="@android:integer/config_shortAnimTime" />

    <alpha
        android:fromAlpha="1"
        android:toAlpha=".4"
        android:duration="@android:integer/config_shortAnimTime" />
</set>

開篇貼出一個簡單的xml動畫作為解析的例子(動畫xml是在res/anim中的)。首先是set,set可以理解為容器,所承載的內容為動畫。有了set,就可以讓多個不同的屬性動畫同時進行播放。在上邊的例子中,一個set(容器)包含了兩個子動畫,分別是scale——縮放動畫和 alpha——透明度動畫。set同樣擁有android:duration屬性,用來定義所有子動畫持續的時間,例子中顯然犯了啥,如果子動畫的時間都是一樣的話可以放在一個set中進行統一定義。set的常用屬性有:
    android:duration="200"
    android:interpolator="@android:interpolator/overshoot"
    android:repeatCount="infinite"
    android:repeatMode="reverse|restart"

android:duration已經說過,定義的是set容器所包含的所有子動畫持續的時間,單位為毫秒ms;

android:interpolator用來定義容器中所有子動畫的插值器,後邊的文章會詳細說明什麼是插值器;

android:repeatCount用來定義容器中所有子動畫的重複次數,infinite為無限;

android:repeateMode用來定義容器中所有子動畫重複時的模式,restart為重頭播放,reverse為回放(很詭異吧)。

PS:上邊這些屬性所有屬性動畫(子動畫)都有,意義相同。

現在看scale縮放動畫,注意對其屬性進行說明(除了android:duration都是scale縮放動畫特有的屬性):

android:pivotX縮放的X軸座標在哪。此X軸所在座標系與我們從小到大所學的略有區別:

Y
|
|
-----------------------→ X
|
↓

區別就是Y軸是向下增長的,X則一樣,是向右增長。縮放時,需要有一個基準座標,pivotX就定義了這個基準座標的X座標部分,注意其屬性值為50%p,就代表了是某個單位的X軸上的一半,不要忘了“p"(percent),這樣就免去了我們要計算這個單位寬度再做處理的麻煩。

android:pivotY縮放基準點的Y軸座標,別忘了是向下增長的,當然瞭如果是中心的話,可以像例子中一樣簡單的定義為50%p。

android:fromXScale縮放開始檢視單位在X軸上的縮放比例為多少,1即為100%,”.5"即為50%,fromYScale同理。

android:toXScale縮放結束後檢視單位在X軸上的縮放比例為多少,Android系統會自動為我們講檢視從from到to做補間動畫(自動連續且自然),toYScale同理。

最後用一句話總結scale縮放動畫的含義:以檢視單位的中心點為準,將其大小從100%所放到85%,持續時間為300毫秒。

PS:Android內建了三個動畫持續時長,分別為@android:integer/config_shortAnimTime(200ms)、@android:integer/config_mediumAnimTime(400ms)、@android:integer/config_longAnimTime(500ms),同時值得注意的是,在Android系統的設定中的開發者選項中,動畫持續時間的除錯選項只有在使用這幾個值時才會生效,如果你使用了自定義的時間,這幾個開發者選項將不能對你的應用生效。

說明完scale縮放動畫後,再來看下一個alpha透明度動畫,這個就要簡單多了,簡單的兩個屬性:

android:fromAlpha動畫開始時的檢視透明度;

android:toAlpha動畫結束時的檢視透明度,同樣的”.4"代表40%,一個“."即帶包百分比。

分析完了整個xml動畫檔案,總結一下這個動畫檔案所描述的動畫行為就是:以檢視中心為基準,進行100% 到85%的縮放,與此同時檢視的透明度由100% 漸變到 40%,整個動畫過程持續200ms。

除了上邊介紹到的scale縮放動畫和alpha透明度動畫,xml動畫還可以定義其他的動畫形式:

    <rotate
        android:fromDegrees=""
        android:toDegrees=""
        android:pivotX=""
        android:pivotY="" />
    <translate
        android:fromXDelta="" android:toXDelta=""
        android:fromYDelta="" android:toYDelta="" />

rotate旋轉動畫和translate位移動畫。

rotate旋轉動畫。圍繞點(pivotX, pivotY)進行旋轉,起始角度為fromDegrees,終止角度為toDegrees。

translate位移動畫。X軸上從fromXDelta移動到toXDelta,Y軸上從fromYDelta移動到toYDelta,很容易理解。

XML動畫的定義在Android L之前就是這些(L版本的動畫只有在L平臺上有效,作為beta版本目前沒有多少裝置覆蓋量),總共包含四種動畫形式:scale縮放,alpha透明度,rotate旋轉,translate位移。等等,是不是缺少了什麼?如果想設計圍繞X或Y軸的旋轉動畫呢?對不起,XML動畫還做不了這個,只能在程式碼中定義,看之後的文章吧。

使用

定義完了XML動畫檔案後如何進行使用呢?首先,明確一下xml動畫能夠應用到哪些地方:Activity、Fragment及所有View。先講一下View,關於View的動畫需要在程式碼中實現,假設我們已經定義了一個XML動畫,名字為fade_zoom_out.xml,獲取這個動畫的物件:

Animation animation = AnimationUtils.loadAnimation(context, R.anim.fade_zoom_out);

Animation和AnimationUtils都是android.view.animation的子類,在API 1中都已經存在,不用擔心相容性。

讓指定的View播放我們剛剛獲取的動畫需要呼叫View的startAnimation方法:

public void startAnimation(Animation animation) 

而很多時候,我們在動畫播放的不同時段需要對View做不同處理,這裡就需要用到動畫監聽器AnimationListener,給動畫設定監聽器,所以必然是Animation類的方法:
public void setAnimationListener(AnimationListener listener)

動畫監聽器AnimationListener很好理解,分別監聽了動畫開始時、結束時、重複播放時:
public static interface AnimationListener {

        void onAnimationStart(Animation animation);

        void onAnimationEnd(Animation animation);

        void onAnimationRepeat(Animation animation);
    }

XML動畫在View上的應用就是這樣了,很簡單吧。

Activiyt的動畫應用有兩種方式,分別是程式碼中和styles.xml中主題覆蓋。個人推崇通過主題定義來應用Activity動畫,這樣整個應用的統一性更好,有問題也比較容易修改。但是還是要說一下程式碼中怎麼將XML動畫應用在Activity上:

public void overridePendingTransition(int enterAnim, int exitAnim)

引數enterAnim和exitAnim都應該是R.anim.xxx的形式。如果沒有動畫則給0。這個函式需要在如startActivity或finish呼叫之後進行呼叫。enterAnim的動畫會應用在進來(新)的那個Activity上,exitAnim的動畫會應用在離去的Activity上。

假設現在有兩個Activity,A和B。從A中執行startActivity(B),然後呼叫overridePendingTransition(enterAnim, exitAnim)。這時B是新的,A是舊的,需要消失。則enterAnim會應用在B上,exitAnim會應用在A上。

主題定義的方式。自定應用主題時,動畫風格的屬性為android:windowAnimationStyle:

<item name="android:windowAnimationStyle">@style/Animation</item>

自定義時,注意parent的選擇:

    <style name="Animation"
           parent="@android:style/Animation.Activity">
    </style>

這樣做是為了保證系統預設動畫的存在,所自定義的會覆蓋系統預設的,沒有自定義的就直接採用系統預設的,不會出現未自定義就直接沒有動畫的效果。

Activity相關動畫屬性的設定有四個:

<item name="android:activityOpenEnterAnimation"></item>
<item name="android:activityOpenExitAnimation"></item>
<item name="android:activityCloseEnterAnimation"></item>
<item name="android:activityCloseExitAnimation"></item>

定義上特別的繞嘴,而且理解上與看字面上的第一印象並不相同。

android:activityOpenEnterAnimation指的是由開啟動作(open)引出的新的Activity進入的動畫是什麼;

android:activityOpenExitAnimation指的是由開啟動作(open)引出新的Activity後,舊的Activity的退出動畫是什麼;

android:activityCloseEnterAnimation指的是由上一個Activity的關閉導致Activity棧中下一個Activity出現時,所出現的這個Activity的動畫效果如何;

android:activityCloseExitAnimation指的是由上一個Activity關閉導致的棧中下一個Activity出現時,這個關閉的Activity退出動畫如何。

果然很繞嘴吧,下邊用一個例子來解釋:

假設有兩個Activity A和B,分別設定了不同的動畫主題。當前視窗顯示的是A,點選A中的某個按鈕會引出B。

當點選A中的這個按鈕時,因為B是因為被開啟引出的,所以B播放的是B主題的activityOpenEnterAnimation動畫,而A播放的是B主題activityOpenExitAnimation動畫(因為A的退出(實際是在Activity棧中後退了一個)是因為B被Open導致的,並不是因為A自身的open或close操作)。

當從B返回時,B介面需要消失,Activity棧決定A介面該出現在前臺。所以可以說A的出現是因為B的close行為導致的。那麼A和B所播放的動畫就是A主題中定義的那些,A因為close行為導致出現,則播放activityCloseEnterAnimation,B是這個close行為中需要退出的介面,則播放activityCloseExitAnimation。

如果還是不理解,就定義幾個差異顯著的動畫來親身測試一下吧,絕對立竿見影的!

Activity的動畫就是這樣,開發過程中還是比較常見的。關於Fragment的相關動畫設定改日再寫,今天晚了,睡覺去~

總結

動畫的使用能夠為應用增光添彩,但是凡事講求度,一旦動畫被濫用,整體的使用者體驗非但不能提升,反而容易讓使用者感覺到十分做作。多講求一些微動畫吧,比如View的微微抖動。而轉場動畫就更應該講求清新淡雅,如果動畫效果過於強烈,使用者一定覺得你的應用執行的很費勁。XML動畫應用比較簡單,一般適合用來做轉場動畫,對於View動畫來說並不夠靈活。