淺析Android動畫(一),View動畫高階例項探究

發表於2016-03-31

本猿自詡Android小白,天然呆穀粉米粉,愛開源,更愛漂亮妹紙((^o^)/~來跟我一起唱:原諒我一生放蕩不羈愛自由~~~請自行腦補掌聲三分鐘^O^);好了好了說人話:本猿中南大學大三狗一個,每天最快樂的時光都與14寸的DeskTop為伴,曾經我是一個熱愛並略懂Java和Android的小白,現在我是一個熱愛並熟悉Java和Android的小白,就這樣!聊技術談夢想歡迎私信 @哈皮小猿_wondertwo

檢視動畫的基本用法

提起 Android 動畫很多初學者就會一臉懵逼二階茫然,當初翻遍圖書館的一大堆入門書籍都找不到一本書在講 Android 動畫機制,好在一顆痴迷技術的心讓我自備燃料有始有終,最後總算弄明白了 Android 動畫到底是個什麼鬼。其實我們有木有經常用手機拍了很多漂亮照片以後,開啟相簿,點選更多,點選自動播放,這些靜態的照片就會連貫的播放起來了有木有?這其實就是逐幀動畫,類似於動畫片的效果。是不是很簡單呢?關於Android動畫的分類我查了很多資料,最初只有兩種動畫即逐幀動畫(frame-by-frame animation)和補間動畫(tweened animation),補間動畫只需要開發者設定動畫的起始值和結束值,中間的動畫由系統自動幫我們完成,下面要介紹的檢視動畫就屬於補間動畫。但是從Android 3.x開始谷歌引入了一種全新的動畫——屬性動畫,相對於檢視動畫只能給View物件設定動畫效果來說,屬性動畫要強大的太多,只要是一個Object物件屬性動畫都能為其設定動畫屬性,不管這個物件能不能看得見,會不會與使用者產生互動。關於屬性動畫的用法會在下一篇部落格中詳細介紹,下面的主要以講解檢視動畫為主。檢視動畫即我們常說的 View Animation, 有四種效果如下:

  • 透明度變化(AlphaAnimation);
  • 位移(TranslateAnimation);
  • 縮放(ScaleAnimation);
  • 旋轉(RotateAnimation);

可以從Android api文件看到檢視動畫 Add in api level 1 ,算是 Android 動畫家族中的老臘肉了。那我們就從檢視動畫的基本用法著手,一步步深入學習!這裡先放上狂炫酷帥的QQ客戶端抖一抖動畫和3D旋轉&電視關閉畫面的自定義動畫,哈哈,這都是用檢視動畫做出來的效果哦!

QQ抖一抖

電視關機畫面&3D旋轉

哈哈,上面的自定義動畫有木有驚豔到你呢?“每一個宅男心中都藏著一個女神”,你看的沒錯!畫面中就是我的女神——張鈞甯。上面的動畫特效是在四種最基本的檢視動畫的基礎上稍加改進出來的,那麼四種基本的檢視動畫效果如何呢?

AlphaAnimation

ScaleAnimation

RotateAnimation

TranslateAnimation

分別對應著透明度變化(AlphaAnimation),縮放(ScaleAnimation),旋轉(RotateAnimation),位移(TranslateAnimation); View 動畫的四種變換效果對應著的 AlphaAnimation , ScaleAnimation , RotateAnimation , TranslateAnimation 這4個動畫類都繼承自 Animation 類,Animation 類是所有檢視動畫類的父類,後面講解的自定義動畫類其實也必須繼承 Animation

並且既可以在程式碼中動態的指定這四種動畫效果,也可以在 xml 檔案中定義, xml 檔案中檢視動畫的目錄是 res/anim/file_name.xml ,與檢視動畫不同, xml 檔案中屬性動畫的目錄是 res/animator/file_name.xml ,不過屬性動畫並不推薦在 xml 檔案中定義,關於屬性動畫請關注我的下一篇部落格哦 。xml 檔案中檢視動畫程式碼如下,透明度動畫對應標籤 ,縮放動畫對應標籤 ,旋轉動畫對應標籤 ,位移動畫對應標籤 ,根標籤 就表示一個動畫集合 AnimationSetshareInterpolator="true" 表示動畫集合中的所有動畫共享插值器,反之shareInterpolator="false" 表示不共享插值器,關於插值器會在第二篇部落格的屬性動畫中詳細介紹。

以上程式碼標籤中的屬性值,其具體含義如下:

  • alpha
    • fromAlpha —- 透明度起始值,0表示完全透明
    • toAlpha —- 透明度最終值,1表示不透明
  • scale
    • fromXScale —- 水平方向縮放的起始值,比如0
    • fromYScale —- 豎直方向縮放的起始值,比如0
    • toXScale —- 水平方向縮放的結束值,比如2
    • toYScale —- 豎直方向縮放的結束值,比如2
    • pivotX —- 縮放支點的x座標
    • pivotY —- 縮放支點的y座標(支點可以理解為縮放的中心點,縮放過程中這點的座標是不變的;支點預設在中心位置)
  • translate
    • fromXDelta —- x起始值
    • toXDelta —- x結束值
    • fromYDelta —- y起始值
    • toYDelta —- y結束值
  • rotate
    • fromDegrees —- 旋轉起始角度
    • toDegrees —- 旋轉結束角度

除此之外,還有一些常見的屬性值,如下:

  • android:duration —- 動畫的持續時間
  • android:fillAfter —- true表示保持動畫結束時的狀態,false表示不保持

上面就是通過 xml 檔案定義的 View 動畫,那怎麼應用上面的動畫呢?也很簡單,通過 View 物件在程式碼中動態載入即可,程式碼如下。值得注意的是,AnimationUtils.loadAnimation(this, R.anim.ani_view) 方法接收兩個引數,第一個是當前的上下文環境,第二個就是我們通過 xml 定義的動畫啦。程式碼如下:

OK那麼問題來了,怎樣直接通過程式碼動態定義 View 動畫呢?也很簡單,先上程式碼如下:

AlphaAni—-透明度動畫程式碼如下,相信你經過前面的部分已經能很容易就看懂這些程式碼了,在 beginAnimation() 方法中,我們在3000ms的時間內把一個 LinearLayout 物件 llAlpha 的透明度從0到1,即從完全透明漸變到完全不透明,然後在 onCreate() 方法中呼叫 beginAnimation() 方法就能以透明度漸變動畫的方式跳轉到 AlphaAni :

ScaleAni—-縮放動畫程式碼如下,與上面的透明度漸變動畫類似,通過 ctrl+左鍵 檢視原始碼可以知道,在建立 ScaleAnimation 縮放動畫的物件的時候, ScaleAnimation(0, 2, 0, 2) 接受的四個引數分別是 ScaleAnimation(float fromX, float toX, float fromY, float toY)

RotateAni—-旋轉動畫程式碼如下,表示把一個 View 物件從起始角度0旋轉到360度,後面的四個引數 RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f 表示以中心位置為旋轉支點:

TranslateAni—-位移動畫程式碼如下,表示把 View 物件從起始座標 (0, 0) 位移到 (200, 300) ,是不是很簡單呢:


檢視動畫的高階用法

趁熱打鐵,接下來正是掌握 View 動畫高階用法的好時機啦,所謂高階用法,其實也很簡單,就是把上面的四種基本效果進行任意的排列組合,然後設定重複次數、重複模式(常用的重複模式有順序、逆向等等),同時啟動或者延遲一定的時間啟動動畫!為了更直觀感受檢視動畫的高階用法,直接上圖請往下看,一種很酷炫的圖片旋轉飛入效果!

四種基本效果的組合動畫

直接上程式碼如下,看過程式碼肯定會覺得,不就是把上面介紹的四種動畫組合到一起了嘛,事實上就是這麼簡單。

唯一不同的是,我們這次是把四個 View 動畫裝進了一個動畫集合(AnimationSet)中,至於動畫集合,你就把他當做普通的 Set 集合使用就好,建立動畫集合時傳入的引數 false 表示動畫集合中裝入的和四個 View 動畫不共享插值器。到這裡你已經學會 View 動畫了,但是後面還有更高階用法呢!


自定義View動畫

當你看完上面的 View 動畫,自定義 View 動畫對你來說已經不在話下,我準備的兩個 demo 你肯定很期待,分別是:模仿QQ客戶端的抖一抖特效,和電視畫面關閉&3D旋轉,效果如下:

QQ抖一抖

模仿QQ客戶端的抖一抖特效,先上程式碼!

上面這段程式碼就是我們自定義的QQ抖一抖動畫了,所有的自定義動畫都需要繼承 android.view.animation.Animation 抽象類,然後重寫 initialize()applyTransformation() 這兩個方法,在 initialize() 方法中對一些變數進行初始化,在 applyTransformation() 方法中通過矩陣修改動畫數值,從而控制動畫的實現過程,這也是自定義動畫的核心。 applyTransformation(float interpolatedTime, Transformation t) 方法在動畫的執行過程中會不斷地呼叫,可以看到接收的兩個引數分別是 float interpolatedTime 表示當前動畫進行的時間與動畫總時間(一般在 setDuration() 方法中設定)的比值,從0逐漸增大到1; Transformation t 傳遞當前動畫物件,一般可以通過程式碼 android.graphics.Matrix matrix = t.getMatrix() 獲得 Matrix 矩陣物件,再設定 Matrix 物件,一般要用到 interpolatedTime 引數,以此達到控制動畫實現的結果。可以看到在上面的程式碼中 t.getMatrix().setTranslate((float) Math.sin(interpolatedTime * 50) * 8, (float) Math.sin(interpolatedTime * 50) * 8) 設定了 Matrix 物件的 Translate ,傳入的引數是一個正弦函式值,這個值是通過 interpolatedTime 引數計算出來的,這樣就實現了動畫在x,y軸兩個方向上的來回抖動效果。

下面是QQ抖一抖動畫的測試類 Activity ,程式碼如下:

接著我們再看一個酷炫的自定義動畫,類似電視機關機畫面和圖片3D旋轉,效果如下!

電視關機畫面&3D旋轉

直接上程式碼,電視關機畫面效果動畫 TVCloseAni 如下:

圖片3D旋轉效果動畫程式碼如下:

下面是電視機關機畫面和圖片3D旋轉動畫的測試類, CustomAniTest 程式碼如下!

唯一不同的是在上面3D旋轉自定義動畫中,我們引入了 Camera 的概念, android.graphics.Camera 中的 Camera 類封裝了 openGL 的3D動畫,因此可以通過 Camera 類實現很多酷炫的3D動畫效果。關於Android中矩陣Matrix的概念,在很多地方都會用到,比如圖片處理,動畫變換等等地方,這裡我就不仔細展開啦!貼上http://www.cnblogs.com/qiengo/archive/2012/06/30/2570874.html#code,看完你肯定能明白矩陣的巨大威力啦,這裡感謝原作者!


在最後附上淺析Android動畫系列的三篇文章:

  1. 淺析Android動畫(一),View動畫高階例項探究 http://www.cnblogs.com/wondertwo/p/5295976.html
  2. 淺析Android動畫(二),屬性動畫與高階例項探究 http://www.cnblogs.com/wondertwo/p/5312482.html
  3. 淺析Android動畫(三),自定義Interpolator與TypeEvaluator http://www.cnblogs.com/wondertwo/p/5327586.html

如果覺得不錯,請繼續關注哦!下一篇將繼續介紹Android屬性動畫哈!

相關文章