Android 三種動畫詳解

pswyjz發表於2021-09-09

1 背景

Android系統提供了很多豐富的API去實現UI的2D與3D動畫,最主要的劃分可以分為如下幾類:

  • View Animation: 檢視動畫在古老的Android版本系統中就已經提供了,只能被用來設定View的動畫。

  • Drawable Animation: 這種動畫(也叫Frame動畫、幀動畫)其實可以劃分到檢視動畫的類別,專門用來一個一個的顯示Drawable的resources,就像放幻燈片一樣。

  • Property Animation: 屬性動畫只對Android 3.0(API 11)以上版本的Android系統才有效,這種動畫可以設定給任何Object,包括那些還沒有渲染到螢幕上的物件。這種動畫是可擴充套件的,可以讓你自定義任何型別和屬性的動畫。

可以看見,當前應用程式開發涉及的主要動畫也就這三大類,我們接下來以類別為基礎來慢慢展開說明。

或者。

方式太簡單了就不說了),如下:
                    
        ...    

 

ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
spaceshipImage.startAnimation(hyperspaceJumpAnimation);

 

上面就是一個標準的使用我們定義的補間動畫的模板。至於補間動畫的使用,Animation還有如下一些比較實用的方法介紹:

Animation類的方法 解釋
reset() 重置Animation的初始化
cancel() 取消Animation動畫
start() 開始Animation動畫
setAnimationListener(AnimationListener listener) 給當前Animation設定動畫監聽
hasStarted() 判斷當前Animation是否開始
hasEnded() 判斷當前Animation是否結束


既然補間動畫只能給View使用,那就來看看View中和動畫相關的幾個常用方法吧,如下:

View類的常用動畫操作方法 解釋
startAnimation(Animation animation) 對當前View開始設定的Animation動畫
clearAnimation() 取消當View在執行的Animation動畫

到此整個Android的補間動畫常用詳細屬性及方法全部介紹完畢,如有特殊的屬性需求可以訪問Android Developer查閱即可。如下我們就來個綜合大演練。

http://blog.csdn.net/yanbober 轉載請註明出處。】

檢視,java方式檢視。

如下圖就是幀動畫的原始碼檔案:

可以看見實際的真實父類就是Drawable。

http://blog.csdn.net/yanbober 轉載請註明出處。】

時序監聽回撥工具 ObjectAnimator  放置在res/animator/目錄下 一個物件的一個屬性動畫 AnimatorSet  放置在res/animator/目錄下 動畫集合

所以可以看見,我們平時使用屬性動畫的重點就在於AnimatorSet、ObjectAnimator、TimeAnimator、ValueAnimator。所以接下來我們就來依次說說如何使用。

Android屬性動畫(注意最低相容版本,不過可以使用開源專案來替代低版本問題)提供了以下屬性:

  • Duration:動畫的持續時間;

  • TimeInterpolation:定義動畫變化速率的介面,所有插值器都必須實現此介面,如線性、非線性插值器;

  • TypeEvaluator:用於定義屬性值計算方式的介面,有int、float、color型別,根據屬性的起始、結束值和插值一起計算出當前時間的屬性值;

  • Animation sets:動畫集合,即可以同時對一個物件應用多個動畫,這些動畫可以同時播放也可以對不同動畫設定不同的延遲;

  • Frame refreash delay:多少時間重新整理一次,即每隔多少時間計算一次屬性值,預設為10ms,最終重新整理時間還受系統程式排程與硬體的影響;

  • Repeat Country and behavoir:重複次數與方式,如播放3次、5次、無限迴圈,可以讓此動畫一直重複,或播放完時向反向播放;

接下來先來看官方為了解釋原理給出的兩幅圖(其實就是初中物理題,不解釋):


上面就是一個線性勻速動畫,描述了一個Object的X屬性運動動畫,該物件的X座標在40ms內從0移動到40,每10ms重新整理一次,移動4次,每次移動為40/4=10pixel。 
上面是一個非勻速動畫,描述了一個Object的X屬性運動動畫,該物件的X座標在40ms內從0移動到40,每10ms重新整理一次,移動4次,但是速率不同,開始和結束的速度要比中間部分慢,即先加速後減速。

接下來我們來詳細的看一下,屬性動畫系統的重要組成部分是如何計算動畫值的,下圖描述瞭如上面所示動畫的實現作用過程。

其中的ValueAnimator是動畫的執行類,跟蹤了當前動畫的執行時間和當前時間下的屬性值;ValueAnimator封裝了動畫的 TimeInterpolator時間插值器和一個TypeEvaluator型別估值,用於設定動畫屬性的值,就像上面圖2非線性動畫 裡,TimeInterpolator使用了AccelerateDecelerateInterpolator、TypeEvaluator使用了 IntEvaluator。

為了執行一個動畫,你需要建立一個ValueAnimator,並且指定目標物件屬性的開始、結束值和持續時間。在呼叫start後,整個動畫過程 中, ValueAnimator會根據已經完成的動畫時間計算得到一個0到1之間的分數,代表該動畫的已完成動畫百分比。0表示0%,1表示100%,譬如上 面圖一線性勻速動畫中總時間 t = 40 ms,t = 10 ms的時候是 0.25。

當ValueAnimator計算完已完成動畫分數後,它會呼叫當前設定的TimeInterpolator,去計算得到一個 interpolated(插值)分數,在計算過程中,已完成動畫百分比會被加入到新的插值計算中。如上圖2非線性動畫中,因為動畫的運動是緩慢加速的, 它的插值分數大約是 0.15,小於t = 10ms時的已完成動畫分數0.25。而在上圖1中,這個插值分數一直和已完成動畫分數是相同的。

當插值分數計算完成後,ValueAnimator會根據插值分數呼叫合適的 TypeEvaluator去計算運動中的屬性值。

好了,現在我們來看下程式碼就明白這段話了,上面圖2非線性動畫裡,TimeInterpolator使用了 AccelerateDecelerateInterpolator、TypeEvaluator使用了IntEvaluator。所以這些類都是標準的 API,我們來看下標準API就能類比自己寫了,如下:

首先計算已完成動畫時間分數(以10ms為例):t=10ms/40ms=0.25。

接著看如下原始碼如何實現計算差值分數的:

public class AccelerateDecelerateInterpolator extends BaseInterpolator        implements NativeInterpolatorFactory {    public AccelerateDecelerateInterpolator() {
    }
    ......    //這是我們關注重點,可以發現如下計算公式計算後(input即為時間因子)插值大約為0.15。    public float getInterpolation(float input) {        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }
    ......
}

 

其實AccelerateDecelerateInterpolator的基類介面就是TimeInterpolator,如下,他只有getInterpolation方法,也就是上面我們關注的方法。

public interface TimeInterpolator {    float getInterpolation(float input);
}

 

接著ValueAnimator會根據插值分數呼叫合適的TypeEvaluator(IntEvaluator)去計算運動中的屬性值,如下,因為startValue = 0,所以屬性值:0+0.15*(40-0)= 6。

public class IntEvaluator implements TypeEvaluator {    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {        int startInt = startValue;        return (int)(startInt + fraction * (endValue - startInt));
    }
}

 

這就是官方給的一個關於屬性動畫實現的過程及基本原理解釋,相信你看到這裡是會有些迷糊的,沒關係,你先有個大致概念就行,接下來我們會慢慢進入實戰,因為Android的屬性動畫相對於其他動畫來說涉及的知識點本來就比較複雜,所以我們慢慢來。

):
            
        ...    

 

屬性解釋:

xml屬性 解釋
android:ordering 控制子動畫啟動方式是先後有序的還是同時進行。sequentially:動畫按照先後順序;together(預設):動畫同時啟動;


屬性解釋:

xml屬性 解釋
android:propertyName String型別,必須要設定的節點屬性,代表要執行動畫的屬性(透過名字引用),闢如你可以指定了一個View的”alpha” 或者 “backgroundColor” ,這個objectAnimator元素沒有對外說明target屬性,所以你不能在XML中設定執行這個動畫,必須透過呼叫 loadAnimator()方法載入你的XML動畫資源,然後呼叫setTarget()應用到具備這個屬性的目標物件上(譬如TextView)。
android:valueTo float、int或者color型別,必須要設定的節點屬性,表明動畫結束的點;如果是顏色的話,由6位十六進位制的數字表示。
android:valueFrom 相對應valueTo,動畫的起始點,如果沒有指定,系統會透過屬性的get方法獲取,顏色也是6位十六進位制的數字表示。
android:duration 動畫的時長,int型別,以毫秒為單位,預設為300毫秒。
android:startOffset 動畫延遲的時間,從呼叫start方法後開始計算,int型,毫秒為單位。
android:repeatCount 一個動畫的重複次數,int型,”-1“表示無限迴圈,”1“表示動畫在第一次執行完成後重複執行一次,也就是兩次,預設為0,不重複執行。
android:repeatMode 重複模式:int型,當一個動畫執行完的時候應該如何處理。該值必須是正數或者是-1,“reverse”會使得按照動畫向相反的方向執行,可實現類似鐘擺效果。“repeat”會使得動畫每次都從頭開始迴圈。
android:valueType 關鍵引數,如果該value是一個顏色,那麼就不需要指定,因為動畫框架會自動的處理顏色值。有intType和floatType(預設)兩種:分別說明動畫值為int和float型。


屬性解釋: 
同上屬性,不多介紹。

XML屬性動畫使用方法:

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
    R.animtor.property_animator);set.setTarget(myObject);set.start();

 

http://www.apkbus.com/blog-873055-77172.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/755/viewspace-2812365/,如需轉載,請註明出處,否則將追究法律責任。

相關文章