公共技術點之 Android 動畫基礎

前言:html

這篇文章比較適合有接觸過android動畫編程的開發人員,若是還未接觸過,則先寫個demo感覺下android動畫實現原理再來讀這篇文章,效果纔好。java

如下是轉帖正文:android

 

一 傳統 View 動畫(Tween/Frame)git

1.1 Tween 動畫

主要有 4 中:縮放、平移、漸變、旋轉編程

tween 相關類繼承關係

文件位置: res/anim/filename.xml
編譯資源的數據類型:an Animation
資源引用:
Java: R.anim.filename
XML: @[package:]anim/filename數據結構

<?xml version="1.0" encoding="utf-8"?>  
    <set xmlns:android="http://schemas.android.com/apk/res/android"  
        android:interpolator="@[package:]anim/interpolator_resource"  
        android:shareInterpolator=["true" | "false"] >  
        <alpha  
        android:fromAlpha="float"  
        android:toAlpha="float" />  
        <scale  
        android:fromXScale="float"  
        android:toXScale="float"  
        android:fromYScale="float"  
        android:toYScale="float"  
        android:pivotX="float"  
        android:pivotY="float" />  
        <translate  
        android:fromXDelta="float"  
        android:toXDelta="float"  
        android:fromYDelta="float"  
        android:toYDelta="float" />  
        <rotate  
        android:fromDegrees="float"  
        android:toDegrees="float"  
        android:pivotX="float"  
        android:pivotY="float" />  
        <set>  
        ...  
        </set>  
    </set>

佈局文件必須有一個獨立的根元素,能夠是 <alpha>,<scale><translate><rotate><set>(持有一組其它的動畫元素,甚至能夠是內嵌的 set 元素) 中的一個app

1.1.1 <set>

一個持有其它動畫元素的容器 <alpha><scale><translate>,<rotate>或者其它 <set> 元素框架

屬性
Android:interpolator
應用於動畫的插值器。該值必須是一個指定了插值器資源的引用(不是一個插值器的類名),在平臺中有缺省的插值器資源可使用,或者你能夠建立本身的插值器資源,能夠看下面關於插值器的討論。
android:shareInterpolator
Boolean 值, true:表明在全部的子元素中共享同一個插值器ide

1.1.2 <alpha>

A fade-in or fade-out animation. Represents an AlphaAnimation. 一個漸入漸出的動畫,對應的 java 類爲 AlphaAnimation。函數

屬性
android:fromAlpha
android:toAlpha
表明動畫開始和結束時透明度,0.0 表示徹底透明,1.0 表示徹底不透明,Float 值

1.1.3 <scale>

能夠實現動態調控件尺寸的效果,經過設置 pivotX 和 pivotY 你能夠指定 image 縮放的中心點,好比:若是這些值是 0,則表示左上角,全部的縮放變化將沿着右下角的軌跡運動。對應的類爲:ScaleAnimation
屬性
android:fromXScale
android:toXScale
android:fromYScale
android:toYScale
Float 值,爲動畫起始到結束時,X、Y 座標上的伸縮尺寸
0.0 表示收縮到沒有
1.0 表示正常無伸縮

android:pivotX
android:pivotY
表明縮放的中軸點 X/Y 座標,浮點值
若是咱們想表示中軸點爲圖像的中心,咱們能夠把兩個屬性值定義成 0.5 或者 50%。

1.1.4 <translate>

表明一個水平、垂直的位移。對應的類爲 TranslateAnimation. 屬性
android:fromXDelta 屬性表明起始 X 方向的位置
android:toXDelta
android:fromYDelta
android:toYDelta

表明動畫起始或者結束 X / Y 方向上的位置,Float 或者百分比值
浮點數 num%、num%p 分別相對於自身或者父控件
若是以浮點數字表示,是一個絕對值,表明相對自身原始位置的像素值;
若是以 num%表示,表明相對於本身的百分比,好比 toXDelta 定義爲 100%就表示在 X 方向上移動本身的 1 倍距離
若是以 num%p 表示,表明相對於父類組件的百分比。

1.1.5 <rotate>

是旋轉動畫,與之對應的 Java 類是 RotateAnimation

屬性
android:fromDegrees
android:toDegrees
表明起始和結束的角度,浮點值,單位:度

android:pivotX 屬性表明旋轉中心的 X 座標值
android:pivotY 屬性表明旋轉中心的 Y 座標值
Float 值或者百分比
這兩個屬性也有三種表示方式,可是 X 軸都是相對方向都是 Left,Y 軸都是相對於 Top
浮點數、num%、num%p;
數字方式表明相對於自身左邊緣的像素值,
num%方式表明相對於自身左邊緣或頂邊緣的百分比,
num%p 方式表明相對於父容器的左邊緣或頂邊緣的百分比

屬性
android:fromDegrees
android:toDegrees
開始和結束時的弧度位置,單位是度,Float 值

調用代碼

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

另外,在動畫中,若是咱們添加了 android:fillAfter="true"後,這個動畫執行完以後保持最後的狀態;android:duration="integer"表明動畫持續的時間,單位爲毫秒。

1.1.6 插值器

用於修改一個動畫過程當中的速率,能夠定義各類各樣的非線性變化函數,好比加速、減速等
在 Android 中全部的插值器都是 Interpolator 的子類,經過 android:interpolator 屬性你能夠引用不一樣的插值器。下面是幾種插值器:

插值器

你能夠經過下面的方式使用它們

<set android:interpolator="@android:anim/accelerate_interpolator">  
        ...  
</set>

自定義插值器 若是你對系統提供的插值器不滿意,咱們能夠建立一個插值器資源修改插值器的屬性,好比修改 AnticipateInterpolator 的加速速率,調整 CycleInterpolator 的循環次數等。爲了完成這種需求,咱們須要建立 XML 資源文件,而後將其放於/res/anim 下,而後再動畫元素中引用便可。咱們先來看一下幾種常見的插值器可調整的屬性:

<?xml version="1.0" encoding="utf-8"?>  
    <InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android"  
        android:attribute_name="value"  
 />

咱們先來看一下幾種常見的插值器可調整的屬性:

<accelerateDecelerateInterpolator> 無

<accelerateInterpolator> android:factor 浮點值,加速速率,默認爲 1

<anticipateInterploator> android:tension 浮點值,起始點後退的張力、拉力數,默認爲 2

<anticipateOvershootInterpolator> android:tension 同上 android:extraTension 浮點值,拉力的倍數,默認爲 1.5(2 * 1.5)

<bounceInterpolator> 無

<cycleInterplolator> android:cycles int,循環的個數,默認爲 1

<decelerateInterpolator> android:factor 浮點值,減速的速率,默認爲 1

<linearInterpolator> 無

<overshootInterpolator> 浮點值,超出終點後的張力、拉力,默認爲 2

好比:res/anim/my_overshoot_interpolator.xml:

<?xml version="1.0" encoding="utf-8"?>  
<overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android"  
android:tension="7.0"/>  
    This animation XML will apply the interpolator:  
    <scale xmlns:android="http://schemas.android.com/apk/res/android"  
        android:interpolator="@anim/my_overshoot_interpolator"  
        android:fromXScale="1.0"  
        android:toXScale="3.0"  
        android:fromYScale="1.0"  
        android:toYScale="3.0"  
        android:pivotX="50%"  
        android:pivotY="50%"  
        android:duration="700" />

若是簡單的修改插值器的屬性值還不可以知足咱們的需求,那麼就本身來經過實現 Interpolator 接口來定義本身的插值器了 由於上面全部的 Interpolator 都實現了 Interpolator 接口,這個接口定義了一個方法:float getInterpolation(float input); 此方法由系統調用,input 表明動畫的時間,在 0 和 1 之間,也就是開始和結束之間。

線性(勻速)插值器定義以下:

public float getInterpolation(float input) {    
        return input;    
}

加速減速插值器定義以下:

public float getInterpolation(float input) {    
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;    
}

1.2 Frame 動畫

文件目錄:res/drawable/filename.xml
編譯資源數據類型 AnimationDrawable
資源引用:
Java: R.drawable.filename
XML: @[package:]drawable.filename

<?xml version="1.0" encoding="utf-8"?>  
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
   android:oneshot=["true" | "false"] >  
    <item  
        android:drawable="@[package:]drawable/drawable_resource_name"  
        android:duration="integer" />  
</animation-list>

1.2.1 <animation-list>

必須做爲根元素,包含一個或者多個根元素
屬性:android:oneshot :true:只執行一次動畫,false:循環執行

1.2.2 <item>

A single frame of animation. Must be a child of a <animation-list> element. 一幀獨立動畫,必須是<animation-list>的子元素

屬性
android:drawable
Drawable 資源,用於這一幀的圖片
android:duration
Integer 類型.該幀的時長,單位爲毫秒 milliseconds.

res/anim/rocket.xml:

<?xml version="1.0" encoding="utf-8"?>  
        <animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
            android:oneshot="false">  
            <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />  
            <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />  
            <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />  
        </animation-list>

調用代碼

ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);  
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);  
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();  
rocketAnimation.start();

二. Property Animation

2.1 Property Animation 的工做方式

Property Animation 動畫有兩個步聚:
1.計算屬性值
2.爲目標對象的屬性設置屬性值,即應用和刷新動畫

2.1.1 計算屬性值

屬性值計算

過程一:計算已完成動畫分數 elapsed fraction 爲了執行一個動畫,你須要建立一個 ValueAnimator,而且指定目標對象屬性的開始、結束值和持續時間。在調用 start 後的整個動畫過程當中, ValueAnimator 會根據已經完成的動畫時間計算獲得一個 0 到 1 之間的分數,表明該動畫的已完成動畫百分比。0 表示 0%,1 表示 100%。

過程二:計算插值(動畫變化率)interpolated fraction 當 ValueAnimator 計算完已完成動畫分數後,它會調用當前設置的 TimeInterpolator,去計算獲得一個 interpolated(插值)分數,在計算過程當中,已完成動畫百分比會被加入到新的插值計算中。

過程三:計算屬性值 當插值分數計算完成後,ValueAnimator 會根據插值分數調用合適的 TypeEvaluator 去計算運動中的屬性值。
以上分析引入了兩個概念:已完成動畫分數(elapsed fraction)、插值分數( interpolated fraction )。

2.2 核心類

屬性動畫類繼承關係

2.2.1 Interpolators

插值器:時間的函數,定義了動畫的變化律。
插值器只需實現一個方法:getInterpolation(float input),其做用就是把 0 到 1 的 elapsed fraction 變化映射到另外一個 interpolated fraction。 Interpolator 接口的直接繼承自TimeInterpolator,內部沒有任何方法,而TimeInterpolator只有一個getInterpolation方法,因此全部的插值器只需實現getInterpolation方法便可。
傳入參數是正常執行動畫的時間點,返回值是調用者真正想要它執行的時間點。傳入參數是{0,1},返回值通常也是{0,1}。{0,1}表示整段動畫的過程。中間的 0.二、0.3 等小數表示在整個動畫(本來是勻速的)中的位置,其實就是一個比值。若是返回值是負數,會沿着相反的方向執行。若是返回的是大於 1,會超出正方向執行。也就是說,動畫可能在你指定的值上下波動,大多數狀況下是在指定值的範圍內。
getInterpolation(float input)改變了默認動畫的時間點 elapsed fraction,根據時間點 interpolated fraction 獲得的是與默認時間點不一樣的屬性值,插值器的原理就是經過改變實際執行動畫的時間點,提早或延遲默認動畫的時間點來達到加速/減速的效果。動畫插值器目前都只是對動畫執行過程的時間進行修飾,並無對軌跡進行修飾。

簡單點解釋這個方法,就是當要執行 input 的時間時,經過 Interpolator 計算返回另一個時間點,讓系統執行另一個時間的動畫效果。

2.2.2 Evaluators

Evaluators 告訴屬性動畫系統如何去計算一個屬性值。它們經過 Animator 提供的動畫的起始和結束值去計算一個動畫的屬性值。 屬性系統提供瞭如下幾種 Evaluators: 1.IntEvaluator
2.FloatEvaluator
3.ArgbEvaluator
這三個由系統提供,分別用於計算 int,float,color 型(十六進制)屬性的計算器
4.TypeEvaluator
一個用於用戶自定義計算器的接口,若是你的對象屬性值類型,不是 int,float,或者 color 類型,你必須實現這個接口,去定義本身的數據類型。

TypeEvaluator接口只有一個方法,就是evaluate()方法,它容許你使用的 animator 返回一個當前動畫點的屬性值。

TimeInterpolator 和 TypeEvaluator 的區別
首先明確動畫屬性值的計算包括三步,其中第二步和第三步分別須要藉助TimeInterpolatorTypeEvluator完成。

TypeEvaluator所作的是根據數據結構計算最終的屬性值,容許你定義本身的數據結構,這是官方對它的真正定義,若是你所定義的屬性值的數據類型不是 float、int、color 類型,那麼你須要實現 TypeEvaluator 接口的evaluate()方法,本身進行屬性值的計算

Interpolator更傾向於你定義一種運動的變化率,好比勻速、加速、減速等,官方對 Interpolator 的定義也確實是這樣的:

A time interpolator defines the rate of change of an >animation. This allows animations to have non-linear >motion, such as acceleration and deceleration.

對於自定義高級動畫時,弄清TimeInterpolatorTypeEvaluator很是重要,若是你但願要自定義本身的動畫,那麼這兩個函數確定是關鍵部分,一個是定義動畫變化率,一個是定義數據結構和屬性值計算方式,二者共同決定了一個動畫的運動。

2.2.3 ValueAnimator

屬性動畫中的主要的時序引擎,如動畫時間,開始、結束屬性值,相應時間屬性值計算方法等。包含了全部計算動畫值的核心函數。也包含了每個動畫時間上的細節,信息,一個動畫是否重複,是否監聽更新事件等,而且還能夠設置自定義的計算類型。

使用 ValueAnimator 實現動畫須要手動更新:

ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.addUpdateListener(new AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        Log.i("update", ((Float) animation.getAnimatedValue()).toString());
    }
});
animation.setInterpolator(new CycleInterpolator(3));
animation.start();

2.2.4 ObjectAnimator

繼承自ValueAnimator,容許你指定要進行動畫的對象以及該對象的一個屬性。該類會根據計算獲得的新值自動更新屬性。也就是說上 Property Animation 的兩個步驟都實現了。大多數的狀況,你使用ObjectAnimator就足夠了,由於它使得目標對象動畫值的處理過程變得簡單,不用再向ValueAnimator那樣本身寫動畫更新的邏輯。但ObjectAnimator有必定的限制,好比它須要目標對象的屬性提供指定的處理方法,這個時候你須要根據本身的需求在ObjectAnimatorValueAnimator中作個選擇了,看哪一種實現更簡便。

ObjectAnimator的自動更新功能,依賴於屬性身上的settergetter方法,因此爲了讓ObjectAnimator可以正確的更新屬性值,你必須聽從如下規範:

  1. 該對象的屬性必須有getset方法(方法的格式必須是駝峯式),方法格式爲 set(),由於 ObjectAnimator 會自動更新屬性,它必須可以訪問到屬性的setter方法,好比屬性名爲foo,你就須要一個setFoo()方法,若是 setter 方法不存在,你有三種選擇:
    a.添加 setter 方法
    b.使用包裝類。經過該包裝類經過一個有效的 setter 方法獲取或者改變屬性值的方法,而後應用於原始對象,好比 NOA 的AnimatorProxy
    c.使用 ValueAnimator 代替

(這 3 點的意思總結起來就是必定要有一個setter方法,讓ObjectAnimator可以訪問到)

  1. 若是你爲 ObjectAnimator 的工廠方法的可變參數只傳遞了一個值,那麼會被做爲動畫的結束值。

  2. 注意,屬性的getter方法和setter方法必須必須是相對應的,好比你構造了一個以下的ObjectAnimator,那麼gettersetter方法就應該爲:

    targetObject.setPropName(float) 和 targetObject.getPropName(float) :
    ObjectAnimator.ofFloat(targetObject, "propName", 1f)
  3. 根據動畫的目標屬性或者對象不一樣,你可能須要調用某一個 View 的invalidate方法,根據新的動畫值去強制屏幕重繪該 View。能夠在onAnimateonUpdate()回調方法中去作。好比,對一個 Drawable 的顏色屬性進行動畫,只有當對象重繪自身的時候,纔會致使該屬性的更新,(不像平移或者縮放那樣是實時的)。一個 View 的全部 setter 屬性方法,好比setAlpha()setTranslationX()均可以適當的更新 View。所以你不須要在重繪的時候爲這些方法傳遞新的值。更多關於 Listener 的信息,能夠參考第四部分 Animation Listeners。

簡單總結下: 當你不但願向外暴露Setter方法的時候,或者但願獲取到動畫值統一作處理的話,亦或只須要一個簡單的時序機制(擁有動畫的各類值)的話,那麼你能夠選擇使用ValueAnimator,它更簡單。若是你就是但願更新動畫,爲了簡便,可使用ObjectAnimator,但自定義的屬性必須有settergetter方法,而且它們必須都是標準的駝峯式(確保內部可以調用),必須有結束值。你能夠實現Animator.AnimatorListener接口根據本身的需求去更新 View。

2.2.5 AnimatorSet

提供組合動畫能力的類。並可設置組中動畫的時序關係,如同時播放、有序播放或延遲播放。Elevator會告訴屬性動畫系統如何計算一個屬性的值,它們會從Animator類中獲取時序數據,好比開始和結束值,並依據這些數據計算動畫的屬性值。

小結: TypeEvaluator
定義了屬性值的計算方式,有 int,float,color 類型,根據屬性的開始、結束值和插值一塊兒計算出當前時間的屬性值,終極方法,整個動畫屬性值計算過程的結尾。

TimeInterpolation
插值器都必須實現的接口,定義了動畫的變化率,如線性,非線性。

ValueAnimatorObjectAnimator
二者均可以進行屬性動畫,可是ObjectAnimator更加簡單,不用去作更新屬性值的計算,可是必需要提供標準的settergetter方法,讓ObjectAnimator可以獲取和更新屬性值。

2.2.6 ViewPropertyAnimator

能夠方便的爲某個 View 的多個屬性添加並行的動畫,只使用一個ViewPropertyAnimator對象就能夠完成。它的行爲更像一個ObjectAnimator,由於它修改的是對象的實際屬性值。但它爲一次性給多個屬性添加動畫提供了方便,並且使用ViewPropertyAnimator的代碼更連貫更易讀。
下面的代碼段分別展現了使用多個ObjectAnimator對象、一個ObjectAnimator對象、 ViewPropertyAnimator同時爲一個 View 的 X 和 Y 屬性添加動畫的示例:

多個 ObjectAnimator 結合 AnimatorSet 實現

ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();

一個 ObjectAnimator 結合多個 PropertyValuesHolder 實現

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();

ViewPropertyAnimator: 只需一行代碼

myView.animate().x(50f).y(100f);//myView.animate()直接返回一個 ViewPropertyAnimator 對象

2.2.7 PropertyValuesHolder

顧名思義,該類持有屬性,相關屬性值的操做以及屬性的 setter,getter 方法的建立,屬性值以 Keyframe 來承載,最終由 KeyframeSet 統一處理。

2.2.8 KeyFrame

一個keyframe對象由一對 time / value 的鍵值對組成,能夠爲動畫定義某一特定時間的特定狀態。
每一個keyframe能夠擁有本身的插值器,用於控制前一幀和當前幀的時間間隔間內的動畫。

Keyframe.ofFloat(0f,0f); 第一個參數爲:要執行該幀動畫的時間節點(elapsed time / duration)
第二個參數爲屬性值。
所以若是你想指定某一特定時間的特定狀態,那麼簡單的使用 ObjectAnimator就知足不了你了,由於,ObjectAnimator.ofInt(....)相似的工廠方法,沒法指定特定的時間點的狀態。

每一個 KeyFrame 的 Interpolator
每一個KeyFrame其實也有個Interpolator。若是沒有設置,默認是線性的。以前爲Animator設置的Interpolator是整個動畫的,而系統容許你爲每一KeyFrame的單獨定義Interpolator,系統這樣作的目的是容許你在某一個keyFrame作特殊的處理,也就是總體上是按照你的插值函數來計算,可是,若是你但願某個或某些KeyFrame會有不一樣的動畫表現,那麼你能夠爲這個keyFrame設置Interpolator

所以,Keyframe 的定製性更高,你若是想精確控制某一個時間點的動畫值及其運動規律,你能夠本身建立特定的 Keyframe

Keyframe 使用
爲了實例化一個keyframe對象,你必須使用某一個工廠方法:ofInt(), ofFloat(), or ofObject() 去獲取合適的keyframe類型,而後你調用ofKeyframe工廠方法去獲取一個PropertyValuesHolder對象,一旦你擁有了該對象,你能夠將 PropertyValuesHolder 做爲參數獲取一個Animator,以下:

Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);//動畫屬性名,可變參數
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)
rotationAnim.setDuration(5000);

2.2.9 KeyFrameSet

根據 Animator 傳入的值,爲當前動畫建立一個特定類型的 KeyFrame 集合。
一般經過 ObjectAnimator.ofFloat(...)進行賦值時,這些值實際上是經過一個 KeyFrameSet 來維護的
好比:

ObjectAnimator.ofFloat(target, "translateX", 50, 100, 200);

調用者傳入的 values 爲 50,100,200,則 numKeyframs = 3,那麼建立出相應的 Keyframe 爲: Keyframe(0,50),Keyframe(1/2,100),Keyframe(1,200), 時間點 0,1/2,1 都是按比例劃分的

public static KeyframeSet ofFloat(float... values) {
        int numKeyframes = values.length;
        FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)];
        if (numKeyframes == 1) {
            keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f);
            keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]);
        } else {
            keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]);
            for (int i = 1; i < numKeyframes; ++i) {
                keyframes[i] = (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]);//這裏是關鍵
            }
        }
        return new FloatKeyframeSet(keyframes);
    }

2.3 在 XML 中聲明屬性動畫

經過在 XML 中定義的動畫,能夠很方便的在多個 Activities 中重用並且更容易編輯,複用性強。爲了區分新的屬性動畫,從 3.1 開始,你應res/animator/下存放屬性動畫的資源文件,使用animator文件夾是可選的,可是若是你想在 Eclipse ADT 插件中使用佈局編輯工具(ADT 11.0.0+),就必須在res/animator文件夾下存放了,由於 ADT 只會查找res/animator文件夾下的屬性動畫資源文件。

屬性動畫支持的 Tag 有
ValueAnimator - <animator>
ObjectAnimator - <objectAnimator>
AnimatorSet - <set>

<set android:ordering="sequentially">
    <set>
        <objectAnimator
            android:propertyName="x"
            android:duration="500"
            android:valueTo="400"
            android:valueType="intType"/>
        <objectAnimator
            android:propertyName="y"
            android:duration="500"
            android:valueTo="300"
            android:valueType="intType"/>
    </set>
    <objectAnimator
        android:propertyName="alpha"
        android:duration="500"
        android:valueTo="1f"/>
</set>
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
    R.anim.property_animator);
set.setTarget(myObject);
set.start();

目錄 res/animator/filename.xm

編譯後的資源爲
ValueAnimatorObjectAnimator, or AnimatorSet 

XML 文件的根元素必須爲<set>,<objectAnimator>, or <valueAnimator>之一。也能夠在一個 set 中組織不一樣的動畫,包含其它<set>元素,也就是說,能夠嵌套。

<set  
  android:ordering=["together" | "sequentially"]>  

    <objectAnimator  
        android:propertyName="string"  
        android:duration="int"  
        android:valueFrom="float | int | color"  
        android:valueTo="float | int | color"  
        android:startOffset="int"  
        android:repeatCount="int"  
        android:repeatMode=["repeat" | "reverse"]  
        android:valueType=["intType" | "floatType"]/>  

    <animator  
        android:duration="int"  
        android:valueFrom="float | int | color"  
        android:valueTo="float | int | color"  
        android:startOffset="int"  
        android:repeatCount="int"  
        android:repeatMode=["repeat" | "reverse"]  
        android:valueType=["intType" | "floatType"]/>  

    <set>  
        ...  
    </set>  
</set>

2.3.2 元素介紹

2.3.2.1 <set>

動畫集合節點,有一個屬性 ordering,表示它的子動畫啓動方式是前後有序的仍是同時。

屬性
sequentially:動畫按照前後順序
together (default) :動畫同時啓動

2.3.2.2 <objectAnimator>

一個對象的一個屬性,相應的 Java 類爲:ObjectAnimator

屬性
android:propertyName:
String 類型,必需要設定的值,表明要執行動畫的屬性,經過名字引用,好比你能夠指定了一個 View 的"alpha" 或者 "backgroundColor",這個 objectAnimator 元素沒有暴露 target 屬性,所以不可以在 XML 中執行一個動畫,必須經過調用loadAnimator() 填充你的 XML 動畫資源,而且調用setTarget() 應用到擁有這個屬性的目標對象上。

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 型。

2.3.2.3 <animator>

在一個特定的時間裏執行一個動畫。相對應的是 ValueAnimator.全部的屬性和同樣 android:valueTo
android:valueFrom
android:duration
android:startOffset
android:repeatCount
android:repeatMode
android:valueType
Value Description
floatType (default)

res/animator/property_animator.xml:

<set android:ordering="sequentially">  
    <set>  
        <objectAnimator  
            android:propertyName="x"  
            android:duration="500"  
            android:valueTo="400"  
            android:valueType="intType"/>  
        <objectAnimator  
            android:propertyName="y"  
            android:duration="500"  
            android:valueTo="300"  
            android:valueType="intType"/>  
    </set>  
    <objectAnimator  
        android:propertyName="alpha"  
        android:duration="500"  
        android:valueTo="1f"/>  
</set>

爲了執行該動畫,必須在代碼中將該動畫資源文件填充爲一個 AnimationSet 對象,而後在執行動畫前,爲目標對象設置全部的動畫集合。
簡便的方法就是經過 setTarget 方法爲目標對象設置動畫集合,代碼以下:

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

三 View anim 與 property anim 的比較

View anim 系統

view animation system 提供的能力只可以爲 View 添加動畫。所以若是你想爲非 View 對象添加動畫,就必須本身去實現, view animation system 在 View 動畫的展示方面也是有約束的,只暴露了 View 的不多方面。好比 View 支持縮放和旋轉,但不支持背景顏色的動畫。
view animation system 的另外一劣勢是,其改變的是 View 的繪製效果,真正的 View 的屬性保持不變,好比不管你在對話中如何縮放 Button 的大小,Button 的有效點擊區域仍是沒有應用到動畫時的區域,其位置與大小都不變。
可是 View animation system 只需花費不多時間建立並且只需不多的代碼。若是 View 動畫完成了你全部的動做,或者你存在的代碼已經達到了你想要的效果,就不必使用 property 動畫系統了。

property anim 系統

徹底彌補了 View anim System 的缺陷,你能夠爲一個對象的任何屬性添加動畫,(View 或者非 View),同時對象本身也會被修改。 而且當屬性變化的時候,property Anim 系統會自動的刷新屏幕。
屬性動畫系統在處理動畫方面也更增強勁。更高級的,你能夠指定動畫的屬性,好比顏色,位置,大小,定義動畫的插值器而且同步多個動畫。
而且在 Property Animation 中,改變的是對象的實際屬性,如 Button 的縮放,Button 的位置與大小屬性值都改變了。並且 Property Animation 不止能夠應用於 View,還能夠應用於任何對象。

平時使用的簡單動畫特效,使用 View 動畫就能夠知足,可是若是你想作的更加複雜,好比背景色的動畫,或者不只是 View,還但願對其它對象添加動畫等,那麼你就得考慮使用 Property 動畫了。

更多動畫開源庫及使用,能夠參考我的博客:Android 動畫系列,其中介紹了一些基本使用,也提到了一些 GitHub 上的動畫開源庫,能夠做爲 Android 動畫學習的資料

參考文獻:
http://developer.android.com/guide/topics/resources/animation-resource.html#val-animator-element
http://blog.csdn.net/liuhe688/article/details/6660823
http://developer.android.com/guide/topics/resources/animation-resource.html#Property
http://developer.android.com/guide/topics/graphics/prop-animation.html
http://android-developers.blogspot.jp/2011/02/animation-in-honeycomb.html
http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.html
http://cogitolearning.co.uk/?p=1078
http://www.2cto.com/kf/201306/222725.html
http://my.oschina.net/banxi/blog/135633
http://zhouyunan2010.iteye.com/blog/1972789
http://blog.csdn.net/guolin_blog/article/details/43816093

相關文章
相關標籤/搜索