官方Property Animation翻譯(全部)以及批注

[TOC]

Property Animation

屬性動畫系統是一個強大的框架,幾乎可以將任何東西動畫化。您可以定義一個動畫以隨時間更改任何對象屬性,而不管它是否繪制到屏幕。屬性動畫在指定的時間長度內更改屬性(對象中的字段)值。你可以指定要動畫的對象屬性。例如對象在屏幕上的位置,要為其設置動畫的時間長度以及要在其間進行動畫化的值。
屬性動畫系統允許開發者定義動畫的以下特征:

  • 1:Duration:你可以指定動畫的持續時間。
    默認長度為300 ms。
  • 2:Time interpolation:你可以指定如何根據動畫當前所用時間計算屬性的值。
  • 3:Repeat count and behavior: 你可以指定是否在到達持續時間結束時重復播放動畫,以及重復播放動畫的次數。 還可以指定是否要相反地播放動畫。 將其設置為反向播放動畫向前,然后反復向后,直到達到重復次數。
  • 4:Animator sets:您可以將動畫組合成Sets,可以設置Sets的播放方式,一起播放或順序播放或在指定的延遲之后。
  • 5:Frame refresh delay:你可以指定刷新動畫幀的頻率。 默認設置為每10 ms更新一次,但是應用程序刷新幀的速度最終取決于系統整體的繁忙程度,以及系統可以為底層定時器服務的速度。

Property Animation 的工作原理:

首先,我們來通過一個例子查看一下動畫是如何工作的,圖1描繪了一個假設的對象,是x屬性水平移動的動畫。動畫的持續時間設置為40 ms,行程距離為40像素。 每10 ms,這是默認的幀刷新率,對象水平移動10像素。 在40 ms結束時,動畫停止,物體以水平位置40結束。這是具有線性插值的動畫的示例,意味著物體以恒定的速度移動。


animation-linear.png

你還可以指定具有非線性內插的動畫。圖2示出了對象在動畫開始時加速,并且在動畫結束時減速。 物體仍然在40毫秒內移動40像素,但是非線性。 一開始,這個動畫加速到中途,然后從中途減速直到動畫結束。 如圖2所示,動畫開頭和結尾處的距離小于中間。


animation-nonlinear.png

我們來詳細了解屬性動畫系統的重要組件如何計算動畫,如圖所示:
valueanimator.png

ValueAnimator對象跟蹤動畫的時間,例如動畫已運行多長時間,以及動畫所屬屬性的當前值。ValueAnimator封裝了TimeInterpolator,它定義了動畫插值,還有一個TypeEvaluator,它定義了如何計算動畫屬性的值。例如,在圖2中,使用的TimeInterpolator將為AccelerateDecelerateInterpolator,TypeEvaluator將為IntEvaluator。
要啟動動畫,創建一個ValueAnimator,并為其創建動畫的屬性、動畫持續時間以及它的開始和結束值,然后調用start()方法開始動畫。在整個動畫過程中,ValueAnimator根據動畫的持續時間和經過多少時間,計算0到1之間的經過分數。經過的分數表示動畫完成的時間百分比,0表示0%,1表示100%。
例如,在圖1中,t = 10ms時的經過分數為0.25,因為總持續時間為t =40ms。當ValueAnimator完成計算經過的分數時,它調用當前設置的TimeInterpolator,以計算內插分數(編者按:不是有個插值器么,定義了動畫的快慢方式,比如勻速,先加速后減速)。將經過的時間分數映射到考慮到插值的新分數(編者按:最后根據這個新分數來計算實際的百分比,在上面是實際的運動距離)。例如,在圖2中,由于動畫緩慢加速,所以在t= 10 ms時,內插分數約為.15,小于經過的時間分數.25。 在圖1中,插值分數總是與經過分數相同。
當計算插值分數時,ValueAnimator將根據插值分數,起始值和動畫的結束值,調用相應的TypeEvaluator來計算您要動畫化的屬性值。 例如,在圖2中,t = 10 ms時插值分數為.15,因此此時的屬性值為.15 X(40 - 0)或6。

Property Animation與View Animation有哪些不同

Android 的ViewAnimation系統只提供了給View對象動畫處理的功能,因此,如果你想為非View對象設置動畫效果,則必須自己去實現相關代碼。ViewAnimation系統本身也有限制,它只將View的幾個方面暴露出來讓我們來實現動畫,例如視圖的縮放和旋轉,但是并沒有提供給我們背景顏色(編者按:背景顏色屬于View的屬性,我們可以使用屬性動畫來控制它)。
ViewAnimation系統的另一個缺點是它只修改了View的繪制位置,而不是實際的View本身。例如,如果你通過ViewAnimation系統實現一個按鈕在屏幕上移動的動畫,則動畫可以正確繪制,但你可以單擊按鈕的實際位置不會更改(編者按:也就你點擊的區域不會改變,你可以自己實現來看,雖然View移動了,但是點擊區域還是原來的位置),因此你需要來處理此問題(編者按:如果你知識需要一個動畫,這樣就可以了)。
使用屬性動畫的話,就沒有上面所說的問題。你可以對任何對象(視圖和非視圖)的任何屬性進行動畫處理,并且對象本身實際上進行了修改。屬性動畫系統在執行動畫的方式也更加強大。在高級別上,你可以分配animators (編者按:這個地方官方給的是animators)給你想要執行動畫的屬性,例如顏色,位置或大小,并且可以定義動畫的方面(aspects),例如多個animators的插值(編者按:插值器)和同步。然而,View Animation系統需要較少的時間來設置,并且需要較少的代碼來寫入。如果View Animation系統就可以完成了你想要的動畫效果,則不需要使用屬性動畫。如果使用情況出現的話(編者按:個人認為是如果需要的話),在不同情況下使用這兩種動畫系統也是有意義的。

用ValueAnimator進行動畫處理

ValueAnimator類允許你通過指定一組int,float或顏色值來動畫化。通過調用其中一種工廠方法獲取ValueAnimator:ofInt(),ofFloat()或ofObject()。例如:

ValueAnimator animation = ValueAnimator.ofFloat(0f, 100f);  
animation.setDuration(1000);  
animation.start();

(編者按:這里只是對值進行了處理,并沒有涉及到目標對象以及我們要操作的屬性)
在此代碼中,當start()方法運行時,ValueAnimator將開始計算0到100之間的動畫值,持續時間為1000 ms。
你還可以通過執行以下操作來指定自定義類型進行動畫處理:

ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);  
animation.setDuration(1000);  
animation.start();

(編者按:這里需要我們自己去計算實際的動畫值,你傳入的是object,系統又不知道該怎么去幫你計算,所以只能自行處理,這里是用MyTypeEvaluator繼承自TypeEvaluator來進行處理)
在此代碼中,當start()方法運行時,ValueAnimator將使用MyTypeEvaluator提供的邏輯持續1000 ms,在startPropertyValue和endPropertyValue之間開始計算動畫值。
你可以通過向ValueAnimator對象添加AnimatorUpdateListener來使用動畫值,如以下代碼所示:

animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  
    @Override  
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {  
        // You can use the animated value in a property that uses the  
        // same type as the animation. In this case, you can use the  
        // float value in the translationX property.  
        float animatedValue = (float)updatedAnimation.getAnimatedValue();  
        textView.setTranslationX(animatedValue);  
    }  
});

在onAnimationUpdate()方法中,您可以訪問更新的動畫值,并在其中一個視圖的屬性中使用它。

用ObjectAnimator進行動畫處理

ObjectAnimator是ValueAnimator的一個子類,將ValueAnimator的定時引擎和值計算與將目標對象的命名屬性動畫化的能力相結合。這使得動畫化任何對象更容易,因為不再需要實ValueAnimator.AnimatorUpdateListener,因為動畫屬性會自動更新。
實例化一個ObjectAnimator類似于一個ValueAnimator,但是您還可以指定該對象的屬性(作為一個字符串)的名稱以及值之間的動畫值:

ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f);  
animation.setDuration(1000);  
animation.start();

要使ObjectAnimator正確更新屬性,必須執行以下操作:
一、正在動畫的對象屬性必須以set <PropertyName>()的形式具有setter函數(以駝峰命名的形式)。因為ObjectAnimator在動畫過程中自動更新屬性,所以它必須能夠使用此setter方法訪問該屬性。(編者按:執行的過程是強制將你傳遞的字符串的第一個字母大寫然后和set進行拼接,組成調用對話對象的set方法)
例如,如果屬性名稱為foo,則需要具有setFoo()方法。如果此setter方法不存在,有三個選項:

  • 1:如果有權這樣做,將setter方法添加到類中。
  • 2:使用有權更改的包裝類,并使該包裝器使用有效的setter方法接收該值并將其轉發到原始對象。
  • 3:改用ValueAnimator。

二:如果在ObjectAnimator的方法之一中為values ...參數只指定了一個值,那么那個值假定是動畫的結束值。因此,您正在動畫的對象屬性必須具有用于獲取動畫起始值的getter函數。 getter函數必須以get<PropertyName>()的形式。 例如,如果屬性名稱是foo,則需要使用getFoo()方法。
三:要動畫的屬性的getter(如果需要)和setter方法必須與您指定給ObjectAnimator的起始值和結束值有相同的類型。例如,如果構造以下ObjectAnimator,則必須具有targetObject.setPropName(float)和targetObject.getPropName(float):

ObjectAnimator.ofFloat(targetObject, "propName", 1f)

四:根據您所動畫的屬性或對象,您可能需要在視圖上調用invalidate()方法來強制屏幕使用更新的動畫值重新繪制自己。你可以在onAnimationUpdate()回調中執行此操作。例如,動畫化Drawable對象的color屬性只會導致在Drawable對象重新繪制時更新屏幕。View上的所有屬性setter(如setAlpha()和setTranslationX())都會使View無效,因此在使用新值調用這些方法時,不需要使View無效。 有關偵聽器的更多信息,請參閱有關動態偵聽器的部分。

使用AnimatorSet來控制多個動畫

在許多情況下,你想要播放依賴于其他動畫開始或結束的動畫。Android系統允許將動畫捆綁在一起成AnimatorSet,以便可以指定是同時,順序還是在指定的延遲之后啟動動畫。 您也可以將AnimatorSet對象嵌套在彼此中。
從彈跳球Demo(為了簡化而有所修改)獲取的以下示例代碼以下列方式展示下列的Animators。

  • 1:Plays bounceAnim
  • 2:Plays squashAnim1,squashAnim2,stretchAnim1和stretchAnim2。
  • 3:Plays bounceBackAnim.
  • 4:Plays fadeAnim.
    有關如何使用動畫組合的更完整的示例,請參閱APIDemos中的 Bouncing Balls示例。

Animation Listeners

你可以在動畫持續時間內收聽下面介紹的listeners 的重要事件。
一:Animator.AnimatorListener
- 1:onAnimationStart() - 動畫啟動時調用。
- 2:onAnimationEnd() - 動畫結束時調用。
- 3:onAnimationRepeat() - 當動畫重復時調用。
- 4:onAnimationCancel() - 當動畫被取消時調用。 取消的動畫也會調用OnAnimationEnd(),無論它們如何結束。
二:ValueAnimator.AnimatorUpdateListener
onAnimationUpdate() - 在動畫的每個幀上調用。(默認的幀刷新率是10ms每次),監聽此事件以使用ValueAnimator在動畫期間生成的計算值。要使用該值,使用傳遞給事件的ValueAnimator對象的getAnimatedValue()方法獲取當前動畫值。 如果你使用ValueAnimator,則需要實現此監聽器。
根據你要動畫的屬性或對象,您可能需要在視圖上調用invalidate(),以強制屏幕區域使用新的動畫值重新繪制。 例如,當Drawable對象重新繪制時,可以對Drawable對象的color屬性進行動畫化,只會導致屏幕更新。 View上的所有屬性setter(如setAlpha()和setTranslationX())都會使View無效,因此在使用新值調用這些方法時,不需要使View無效。(前面已經介紹過了)
如果你不想實現Animator.AnimatorListener接口的所有方法,可以擴展AnimatorListenerAdapter類。 AnimatorListenerAdapter類提供了可以選擇覆蓋的方法的空實現。
(編者按:你如果實現Animator.AnimatorListener接口接口的話需要實現下面這四個方法。

    void onAnimationStart(Animator animation);  
    void onAnimationEnd(Animator animation);  
    void onAnimationCancel(Animator animation);  
    void onAnimationRepeat(Animator animation);  

如果你不想實現這么多的話,比如你只需要一個的實現,你就可以使用AnimatorListenerAdapter類,這個類繼承自Animator.AnimatorListener接口和Animator.AnimatorPauseListener接口,這個接口里有兩個方法

    void onAnimationPause(Animator animation);  
    void onAnimationResume(Animator animation);  

所以AnimatorListenerAdapter類里面有上面六個方法的實現,你可以任意選擇一個來進行實現)
谷歌官方給了個栗子:

    ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);  
    fadeAnim.setDuration(250);  
    fadeAnim.addListener(new AnimatorListenerAdapter() {  
    public void onAnimationEnd(Animator animation) {  
        balls.remove(((ObjectAnimator)animation).getTarget());  
    }  

Animating Layout Changes to ViewGroups

屬性動畫系統提供了對ViewGroup對象進行動畫更改的功能,同時也為View對象本身提供了一種簡單的方法。
你可以使用LayoutTransition類為ViewGroup中的布局設置更改動畫。ViewGroup中的View可以在ViewGroup中添加或從ViewGroup中刪除時或當你使用VISIBLE,INVISIBLE或GONE調用View的setVisibility()方法時,看到出現和消失的動畫。當你添加或刪除視圖時,ViewGroup中的其余視圖也可以動畫的進入它們新的位置。
你可以通過調用setAnimator()并傳遞Animator對象和傳遞在LayoutTransition對象中定義以下常亮之一來設置動畫:
LayoutTransition 類中定義的常數:

  • 1:APPEARING - 指示在容器中出現的項目上運行的動畫的標志。
  • 2:CHANGE_APPEARING - 指示由于容器中出現新項目而改變的項目上運行的動畫的標志。
  • 3:DISAPPEARING - 表示在從容器中消失的項目上運行的動畫的標志。
  • 4:CHANGE_DISAPPEARING - 指示由于項目從容器中消失而改變的項目上運行的動畫的標志。
    (編者按:setAnimator源碼如下:)
    public void setAnimator(int transitionType, Animator animator) {  
            switch (transitionType) {  
                case CHANGE_APPEARING:  
                    mChangingAppearingAnim = animator;  
                    break;  
                case CHANGE_DISAPPEARING:  
                    mChangingDisappearingAnim = animator;  
                    break;  
                case CHANGING:  
                    mChangingAnim = animator;  
                    break;  
                case APPEARING:  
                    mAppearingAnim = animator;  
                    break;  
                case DISAPPEARING:  
                    mDisappearingAnim = animator;  
                    break;  
            }  
        }  

你可以為這四種類型的事件定義自己的動畫,以及自定義布局轉換的外觀,或者只是告訴動畫系統使用默認動畫。API Demos中的LayoutAnimations示例顯示了如何為布局轉換定義動畫,然后在要動畫化的View對象上設置動畫。
LayoutAnimationsByDefault及其相應的layout_animations_by_default.xml布局資源文件顯示如何啟用XML中ViewGroups的默認布局轉換。 你唯一需要做的是為ViewGroup設置android:animateLayoutchanges屬性為true。 例如:

<LinearLayout  
    android:orientation="vertical"  
    android:layout_width="wrap_content"  
    android:layout_height="match_parent"  
    android:id="@+id/verticalContainer"  
    android:animateLayoutChanges="true" />

將此屬性設置為true將自動生成從ViewGroup添加或刪除的視圖以及ViewGroup中的其余視圖的動畫。

Using a TypeEvaluator

如果要為Android系統未知的類型設置動畫,您可以通過實現TypeEvaluator接口來創建自己的evaluator 。Android系統已知的類型是int,float或顏色,分別對應IntEvaluator,FloatEvaluator和ArgbEvaluator類型。
在在TypeEvaluator接口中只有一種方法,那就是evaluate()方法。這允許您使用的animator 在動畫的當前位置為動畫屬性返回適當的值。
(編者按:接口源碼如下)

    public interface TypeEvaluator<T> {  
      
        /**  
         * This function returns the result of linearly interpolating the start and end values, with  
         * <code>fraction</code> representing the proportion between the start and end values. The  
         * calculation is a simple parametric calculation: <code>result = x0 + t * (x1 - x0)</code>,  
         * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,  
         * and <code>t</code> is <code>fraction</code>.  
         *  
         * @param fraction   The fraction from the starting to the ending values  
         * @param startValue The start value.  
         * @param endValue   The end value.  
         * @return A linear interpolation between the start and end values, given the  
         *         <code>fraction</code> parameter.  
         */  
        public T evaluate(float fraction, T startValue, T endValue);  
   
    }  

FloatEvaluator類:

    /** 
     * This evaluator can be used to perform type interpolation between <code>float</code> values. 
     */  
    public class FloatEvaluator implements TypeEvaluator<Number> {  
      
        /** 
         * This function returns the result of linearly interpolating the start and end values, with 
         * <code>fraction</code> representing the proportion between the start and end values. The 
         * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>, 
         * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>, 
         * and <code>t</code> is <code>fraction</code>. 
         * 
         * @param fraction   The fraction from the starting to the ending values 
         * @param startValue The start value; should be of type <code>float</code> or 
         *                   <code>Float</code> 
         * @param endValue   The end value; should be of type <code>float</code> or <code>Float</code> 
         * @return A linear interpolation between the start and end values, given the 
         *         <code>fraction</code> parameter. 
         */  
        public Float evaluate(float fraction, Number startValue, Number endValue) {  
            float startFloat = startValue.floatValue();  
            return startFloat + fraction * (endValue.floatValue() - startFloat);  
        }  
    }  

(編者按:這個地方跟官方的不一樣,這里我才用的是API25的源碼,可以看出這就是一個小學的計算。。。)
注意:當ValueAnimator(或ObjectAnimator)運行時,它會計算動畫的當前經過分數(0到1之間的值),然后根據所使用的內插器計算出考慮到插值器的插值分數(也就是實際的運行分數)。 插值分數是您的TypeEvaluator通過分數參數獲得的分數,因此在計算動畫值時不需要考慮插值器。

Using Interpolators

插值器定義如何根據時間的函數計算動畫中的特定值。 例如,你可以指定動畫在整個動畫中線性發生,這意味著動畫在整個時間內均勻移動,或者你可以指定使用非線性時間的動畫,例如,在開始或結束時使用加速或減速 動畫。動畫系統中的插值器從Animators接收代表動畫經過時間的分數。插值器修改這個分數(這個分數只和時間相關),以符合它在提供的類型。(編者按:在源碼中有兩個分數,一個是在插值器之前的,這個分數只和時間相關,另一個是經過插值器修改過的,這個就是實際運行的分數,只有在勻速運動的時候兩個分數是相同的)。
Android系統在android.view.animation包中提供了一組常見的插件。 如果這些都不符合您的需求,您可以實現TimeInterpolator界面并創建自己的。
例如,下面比較默認提供的插值器AccelerateDecelerateInterpolator和LinearInterpolator計算插值分數的不同。
AccelerateDecelerateInterpolator

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

LinearInterpolator

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

下表表示這些內插器為持續1000ms的動畫計算的近似值

ms elapsed Linear Accelerate/Decelerate
0 0 0
200 0.2 0.1
400 0.4 0.345
600 0.6 0.8
800 0.8 0.9
1000 1.0 1.0

Specifying Keyframes

(編者按:先來看一下源碼對于Keyframes是怎么定義的-->該類保存動畫的時間/值對。)
一個Keyframes保存一個時間/值對,在開發者定義的一個特定狀態在動畫的特定時間。每一個keyframe也能夠擁有自己的插值器在前一個keyframe和這個keyframe的時間間隔內去控制動畫的行為。
要實例化一個Keyframe 對象,你必須使用一個工廠方法,即ofInt(),ofFloat()或orObject()來獲取Keyframe的適當類型。(編者按:整篇文章對ofInt等方法都成為factory methods,有知道的朋友可以給我留言)
然后調用ofKeyframe()方法來獲取一個PropertyValuesHolder對象。一旦擁有該對象,你可以通過傳遞PropertyValuesHolder對象和the object獲得一個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(5000ms);  

有關如何使用keyframe的更完整的示例,請參閱APIDemos中的MultiPropertyAnimation示例。

Animating Views

屬性動畫系統允許View對象的流線型動畫,并且相比視圖動畫系統有很多優點。視圖動畫系統通過更改繪制方式來轉換View對象。這是在每個視圖的容器中處理的,因為View本身沒有要處理的屬性。這導致View被動畫化,但是在View對象本身沒有改變。這導致即使它被繪制在屏幕上的不同位置,對象仍然存在于其原始位置的行為。(編者按:之前提到過,點擊區域并沒有發生任何的變化),在Android 3.0中,添加了新的屬性和相應的getter和setter方法來消除這個缺點。
通過更改View對象中的屬性,屬性動畫系統可以在屏幕上動畫化視圖。 另外,Views也會自動調用invalidate()方法,以便在其屬性更改時刷新屏幕(編者按:invalidate()方法會調用draw方法進行重新繪制,在是用Scroller實現彈性動畫的時候會使用到這一點)。
View中便于屬性動畫的新屬性有:

  • 1:translationX and translationY 這些屬性控制視圖位于其左側和頂部坐標中由其布局容器設置的三角形。(編者按:我自己的理解是移動前View的左上角和移動后View的左上角組成的三角形,對不對不清楚)
  • 2:rotation, rotationX, and rotationY:這些屬性控制2D(旋轉屬性)中的旋轉和繞樞軸點的3D旋轉。
  • 3:scaleX and scaleY:這些屬性控制視圖圍繞其樞軸點的2D縮放。
  • 4:pivotX and pivotY: 這些屬性控制樞軸點的位置,旋轉和縮放變換中心都是在該位置。 默認情況下,樞軸點位于對象的中心。
  • 5:x and y:這些是簡單的實用屬性,用于在其容器中描述View的最終位置,作為mLeft和mTop以及translationX和translationY值之和。
  • 6:表示視圖上的Alpha透明度。 默認值為1(不透明),值為0表示完全透明(不可見)。
    要為View對象的屬性(如其顏色或旋轉值)設置動畫效果,您需要做的是創建一個屬性動畫制作器,并指定要設置動畫的View屬性。 例如:
    ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);  

Animating with ViewPropertyAnimator

ViewPropertyAnimator提供了一種簡單的方式來使用單個底層的Animator對象并行地對視圖的多個屬性進行動畫化。 它的行為非常類似于ObjectAnimator,因為它會修改視圖屬性的實際值,但在一次動畫化多個屬性時效率比ObjectAnimatior更高。另外,使用ViewPropertyAnimator的代碼更簡潔易讀。以下代碼展示了使用多個 ObjectAnimator objects,單個ObjectAnimator,以及the ViewPropertyAnimator之間的差異當同時動畫化視圖的x和y屬性。

Multiple ObjectAnimator objects

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

One ObjectAnimator

    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);  

(編者按:簡直簡潔到爆有木有,下面是相關的源碼)

    /** 
         * This method returns a ViewPropertyAnimator object, which can be used to animate 
         * specific properties on this View. 
         * 
         * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View. 
         */  
        public ViewPropertyAnimator animate() {  
            if (mAnimator == null) {  
                mAnimator = new ViewPropertyAnimator(this);  
            }  
            return mAnimator;  
        }  
    /** 
         * This method will cause the View's <code>x</code> property to be animated to the 
         * specified value. Animations already running on the property will be canceled. 
         * 
         * @param value The value to be animated to. 
         * @see View#setX(float) 
         * @return This object, allowing calls to methods in this class to be chained. 
         */  
        public ViewPropertyAnimator x(float value) {  
            animateProperty(X, value);  
            return this;  
        }  
    /** 
         * This method will cause the View's <code>y</code> property to be animated to the 
         * specified value. Animations already running on the property will be canceled. 
         * 
         * @param value The value to be animated to. 
         * @see View#setY(float) 
         * @return This object, allowing calls to methods in this class to be chained. 
         */  
        public ViewPropertyAnimator y(float value) {  
            animateProperty(Y, value);  
            return this;  
        }  

有關ViewPropertyAnimator的更多詳細信息,請參閱相應的Android Developers博客文章。

Declaring Animations in XML

屬性動畫系統允許您使用XML聲明屬性動畫,而不是以編程方式執行。 通過使用XML定義動畫,您可以輕松地在多個活動中重新使用動畫,并更輕松地編輯動畫序列。
要區分使用新屬性動畫API的動畫文件與使用舊版視圖動畫框架的動畫文件,從Android 3.1開始,應將資源動畫的XML文件保存在res / animator /目錄中。
以下屬性動畫類使用以下XML標記支持XML聲明:

  • 1:ValueAnimator - <animator>
  • 2:ObjectAnimator - <objectAnimator>
  • 3:AnimatorSet - <set>
    要查找您可以在XML聲明中使用的屬性,請參閱Animation Resources 。以下示例順序播放兩組對象動畫,第一個是兩個一起播放的動畫。
    <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>  

為了運行此動畫,您必須將代碼中的XML資源inflate到AnimatorSet對象,然后在開始動畫集之前設置所有動畫的目標對象。調用setTarget()為AnimatorSet的所有子項設置單個目標對象。 以下代碼顯示如何執行此操作:

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

你還可以在XML中聲明ValueAnimator,如以下示例所示:

    <animator xmlns:android="http://schemas.android.com/apk/res/android"  
        android:duration="1000"  
        android:valueType="floatType"  
        android:valueFrom="0f"  
        android:valueTo="-100f" />  

要在你的代碼中使用上面的ValueAnimator,你必須inflate 一個對象,添加AnimatorUpdateListener,獲取更新的動畫值,并將其用于其中一個視圖的屬性,如以下代碼所示:

    ValueAnimator xmlAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this,  
            R.animator.animator);  
    xmlAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  
        @Override  
        public void onAnimationUpdate(ValueAnimator updatedAnimation) {  
            float animatedValue = (float)updatedAnimation.getAnimatedValue();  
            textView.setTranslationX(animatedValue);  
        }  
    }); 
    xmlAnimator.start();  

有關ViewPropertyAnimator的更多詳細信息,請參閱相應的Android Developers博客文章。

Implications for UI performance

更新UI的Animators 會為動畫運行的每個幀帶來額外的渲染工作。因此,使用資源密集型動畫可能會對你的應用程序的性能產生負面影響。
為UI創建動畫所需的工作被添加到渲染管道的動畫階段。你可以通過啟用Profile GPU渲染和監視動畫舞臺來確定您的動畫是否影響了您的應用的效果。 有關更多信息,請參閱Profile GPU Rendering Walkthrough

我的csdn博客地址:http://blog.csdn.net/zcl1359205840?viewmode=contents

low_stiffness.gif
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容