編輯:關於android開發
屬性動畫系統是一個健壯 的框架,它幾乎可以允許把任何對象變成動畫。可以根據時間的推移來改變任何對象的屬性來定義一個動畫,而不用關心該對象是否要繪制在屏幕上。屬性動畫是在 指定的時間長度上改變一個屬性(對象中的一個成員字段)的值。要讓某些對象變成動畫,就要給該對象指定想要的動畫屬性,如果對象在屏幕上的位置、動畫的停 留時間以及動畫之間的值等。
屬性動畫系統可以定義以下動畫特性:
1.持續時間(Duration):指定動畫的持續時間。默認長度是300毫秒。
2.時間插值(Time interpolation):這個值能夠做為計算當前動畫運行時間的函數的屬性值來指定,它決定動畫的變化頻率。
3.重復次數和行為(Repeat count and behavior)
這個屬性能夠指定在動畫結束時是否重新播放動畫,以及重復播放的次數。還能夠指定動畫是否能夠反向回播,如果設置了反向回播,那麼動畫就會先向前再向後,重復播放,直到達到播放次數。
4.動畫集合(Animator sets):你能夠把動畫組織到一個邏輯集合中,然後或者同時、或者順序的、或者延遲播放它們。
5.幀刷新延遲(Frame refresh delay):你能夠指定動畫幀的刷新頻率。默認是每10秒中刷新一次,但是應用程序最終的刷新幀的速度依賴與系統的繁忙程度以及系統能夠提供的底層定時器的反應速度。
屬性動畫是如何工作的
首先,讓我們用一個簡單 的例子來看一下動畫的工作方式。圖1繪制了一個假想的動畫對象,它用x屬性來表示其在屏幕上的水平位置。動畫的持續時間被設置為40毫秒,並且移動的距離 是40個像素。每10毫秒,是默認的幀刷新頻率,即每10毫秒對象水平移動10個像素。在40毫秒結束時,動畫停止,並且動畫要停留在水平40像素點的位 置上。這是一個線性插值的動畫示例,意味著動畫勻速運動。
圖1.線性動畫示例
還可以指定非線性差值的 動畫。圖2假設了一個加速開始、減速結束的動畫對象,該對象依然在40毫秒內移動了40個像素,但是非線性的。在開始的時候,這個動畫加速運動到一半的位 置,然後開始減速運動直到動畫結束。如圖2所示,對象運行的距離在開始和結束階段要比中間部分短。
圖2.非線性動畫的示例
接下來讓我們更詳細的了解屬性動畫系統的重要組件是如何計算上圖所示動畫。圖3繪制了主類和其他類是如何一起工作的。
圖3.動畫的計算方式
ValueAnimator對象保持著動畫的時間軌跡,如動畫的運行時間,以及動畫屬性的當前值。
ValueAnimator 類封裝了一個TimeInterpolator類,這個類定義了動畫的差值,和一個TypeEvaluator類,這個類定義動畫屬性值的計算方式。例 如,在圖2中TimeInterpolator對象使用AccelerateDecelerateInterpolator定 義,TypeEvaluator使用了IntEvaluator定義。
要啟動一個動畫,就要創 建一個ValueAnimator對象,並且要給該對象設置想要的動畫的屬性的開始和結束值,以及動畫的持續時間。在調用start()方法開始動畫的時 候,整個動畫期間,ValueAnimator對象會根據動畫的持續時間和已經執行的時間,在0和1之間,計算一個elapsed fraction(過去系數)。這個系數代表了動畫已經完成的百分比,0意味著0%、1意味著100%。例如,圖1中,在t = 10毫秒處的過去系數是0.25,因為總的持續時間是t = 40毫秒。
當 ValueAnimator對象完成過去系數的計算時,它會調用當前設置的TimeInterpolator對象,來計算一個差值系數 (interpolated fraction)。差值系數(interpolated fraction)把過去系數(elapsed fraction)映射到一個新的考慮設置時間差值的系數。例如,在圖2中,因為動畫是慢慢的加速,因此在t=10毫秒時,差值系數大約是0.15,它比 過去系數(elapsed fraction)0.25要小。在圖1中,差值系數(interpolated fraction)與過去系數(elapsed fraction)始終相同。
在計算差值系數 (interpolated fraction)時,ValueAnimator對象會調用相應的TypeEvaluator對象,基於差值系數、動畫的開始值、結束值,來計算動畫的 屬性值。例如,在圖2中,在t = 10毫秒處,差值系數是0.15,因此在此時的屬性值應該是0.15*(40 – 0)= 6。
在API Demos示例工程中的com.example.android.apis.animation包,提供了很多如何使用屬性動畫系統的例子。(http://developer.android.com/tools/samples/index.html)
屬性動畫與視圖動畫的差異
視圖動畫提供了只讓View對象具有動畫效果的能力,因此想要非View對象具有動畫效果,就得自己實現動畫效果的代碼。事實上,視圖動畫系統也受到了限制,它只會把很少的View對象的特征暴露給動畫效果,如例如,View對象的縮放和旋轉,但是沒有背景色,等等。
視圖動畫的另一個缺點是,它僅能夠在繪制View對象時被修改,並且不是實際的View對象本身。例如,如果要讓一個按鈕,以動畫的形式穿越屏幕,按鈕正確的繪制了,但是點擊按鈕的實際位置卻不會改變,因此必須自己來實現這種處理邏輯。
在屬性動畫系統中,這些 現在被徹底刪除,並且能夠讓任何對象的任何屬性具有動畫效果(View對象和非View對象),並且能夠實際修改對象自身。屬性動畫在動畫執行方面也更加 健壯。在高層次上,可以給想要動畫效果的屬性分配動畫執行器,如顏色、位置、尺寸以及能夠定義的動畫特性(如插值和多個動畫的同步等)。
但是,視圖動畫系統需要較少的創建時間和編寫較少的代碼。如果視圖動畫能夠滿足需求,或者既存的代碼已經做了想要完成的動畫效果,就不需要使用屬性動畫效果了。針對不同的情況來選擇使用這兩種不同的動畫系統。
API概要
在android.animation包中能夠找大多數屬性動畫系統的API。因為視圖動畫系統已經在android.view.animation包中定義了很多插值,因此在屬性動畫系統中也能夠使用這些插值。下列表格中介紹了屬性動畫系統的主要組件。
Animator類提供了創建動畫的基本架構。通常不會直接使用這個類,因為它只提供了基本功能,因此要完全的支持動畫值就必須擴展這個類,下表列出了Animator的子類。
表1.Animators
類
說明
ValueAnimator
用於計算處理動畫屬性值 的主要屬性動畫時序引擎。它有所有的計算動畫值的核心功能,並包含了每個動畫的時序細節、動畫是否重復的信息、監聽接收更新事件和設置評估定制類型的能 力。有兩類動畫屬性:1.計算動畫處理的值;2.把這些值設置到要進行動畫處理的對象和屬性上。ValueAnimator類不執行第二類屬性,因此必須 通過ValueAnimator對象來監聽被計算值的變化,並且要自己修改想要的動畫對象的邏輯。更多的信息請看用ValueAnimator類來進行動 畫處理。(http://developer.android.com/guide/topics/graphics/prop-animation.html)
ObjectAnimator
ValueAnimator 類的一個子類,它允許給目標對象和對象屬性設置動畫。這個類在計算新的動畫值的時候,會更新屬性的坐標。大多數時候都會使用ObjectAnimator 類,因為它使得動畫值的處理更加容易。但是,有些時候也會直接使用ValueAnimator類,因為ObjectAnimator類有更多的限制,如在 目標對象上需要指定用於呈現的acessor方法。
AnimatorSet
提供了一種把動畫組織到一起的機制,以便它們能夠彼此相互關聯的運行。你能夠設置動畫在一起播放、順序的播放、或者在指定的延時之後播放。更多的信息請看“用Animator Sets來編排多個動畫”
評價器會告訴屬性動畫系統如何計算給定屬性的值。它們利用Animator類提供時序數據:動畫的開始和結束值,以及基於這些數據計算得來的屬性動畫值。屬性動畫系統提供了下列評價器:
表2.Evaluators
Class/Interface
說明
IntEvaluator
默認的用於評價int類型屬性計算值的評價器
FlaoatEvaluator
默認的用於評價float類型屬性計算值的評價器
ArgbEvaluator
默認的用於評價顏色屬性計算值的評價器,顏色屬性值用十六進制表示。
TypeEvaluator
允許創建自定義評價器的 接口。如果要讓一個非int、float、顏色類型的屬性具有動畫效果,就必須實現這個TypeEvaluator接口,用它來指定如何計算對象屬性動畫 值。如果想要處理有別於int、float和顏色類型默認行為的動畫,也能夠給它們指定一個自定義的TypeEvaluator。如何編寫自定義的評價 器,請看“使用TypeEvaluator”
時間差值給動畫中的時間 函數定義了一個用於計算的具體的值。例如,一個線性過渡的動畫,意味著整個動畫期間動畫都會均勻的移動,或者例如加速開始,減少結束的非線性動畫。表3介 紹了被包含在android.view.animation包中差值。如果那裡沒有適合你需要的差值,你可以實現TimeInterpolator接口, 創建自己的差值。如何編寫自定義差值的更多信息,請看“使用差值”。
表3.Interpolators
Class/Interface
說明
AccelerateDecelerateInterpolator
變化頻率在開始和結尾處慢,而在中間部分加速
AccelerateInterpolator
變化頻率在開始慢,然後加速
AnticipateInterpolator
先向後,然後向前拋出(拋物運動)
AnticipateOvershootInterpolator
先向後,向前拋出並超過目標值,然後最終返回到目標值。
BounceInterpolator
在結束時反彈
CycleInterpolator
用指定的循環數,重復播放動畫
DecelerateInterpolator
變化頻率是快出,然後減速
LinearInterpolator
固定的變化頻率
OvershootInterpolator
向前拋出,並超過目標值,然後再返回
TimeInterpolator
實現自定義插值的一個接口
用ValueAnimator來制作動畫
ValueAnimator 類通過設定動畫過程中的int、float或顏色值,來指定動畫播放期間的某些類型的動畫值。通過ValueAnimator類的一個工廠方法來獲取一個 ValueAnimator對象:ofInt()、ofFloat()、ofObject()。例如:
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f); animation.setDuration(1000); animation.start();
在這段代碼中,當start()方法開始執行時,ValueAnimator對象會在1000毫秒的動畫期間內,在0和1之間開始計算動畫的值。
還可以通過下面的做法來指定自定義的動畫類型:
ValueAnimator animation = ValueAnimator.ofObject(newMyTypeEvaluator(), startPropertyValue, endPropertyValue); animation.setDuration(1000); animation.start();
在這段代碼中,在start()方法開始執行的時候,ValueAnimator對象會在1000毫秒的動畫期間內,使用由MyTypeEvaluator對象提供的邏輯,在startPropertyValue和endPropertyValue之間,開始計算動畫的值。
但是,在前一個代碼片段中,不會對一個對象形成實際的影響,因為ValueAnimator對 象沒有直接在對象或屬性上執行操作。這麼做的最大可能是用這些計算值來修改那些想要動畫效果的對象。通過定義ValueAnimator類中響應的事件監 聽器,來處理動畫執行期間的重要事件,如幀更新等。當監聽器執行的時候,就能夠通過調用getAnimateValue()方法獲得指定幀的刷新的計算 值。有關監聽器的更多信息,請看“動畫監聽器”。
用ObjectAnimator來制作動畫
ObjectAnimator類是ValueAnimator類的一個子類,並且把時序引擎和ValueAnimator對象的計算值組合到一起,讓目標對象的命名屬性具備動畫能力。這樣使得讓任意對象具有動畫效果變的更加容易,如不在需要實現ValueAnimator.AnimatorUpdateListener接口,因為被動畫的屬性會自動的更新。
實例化一個ObjectAnimator對象與實例化一個ValueAnimator對象類似,但是,它還需要跟動畫期間的參數一起,指定動畫對象和對象動畫屬性(用一個字符串)的名字:
ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f); anim.setDuration(1000); anim.start();
要正確的更新ObjectAnimator對象的屬性,必須做以下事情:
1.動畫效果的屬性必須有一個set
A.如果你權利這麼做,就要在這個類中添加設置器方法;
B.使用一個你有權改變的包裝器類,並且這個包裝器能夠用一個有效的設置方法來接收動畫值,而且還要能夠把這個值轉發給初始對象。
C.使用ValueAnimator類來代替。
2.如果你只在ObjectAnimator類的一個工廠方法中指定了一個values…參數,那麼該值會被假定為動畫的結束值。因此,該對象的動畫效果屬性就必須要有一個獲取方法,用於獲得動畫的開始值。這個獲取方法必須使用get
3.動畫屬性的獲取(如果需要)和設置方法必須操作相同類型的指定給ObjectAnimator對象開始和結束值。例如,如果構建一個下面這樣的ObjectAnimator對象,就必須要有targetObejct.setPropName(float)和targetObject.getPropName(float)方法:
ObjectAnimator.ofFloat(targetObject,"propName", 1f)
4.根據屬性或對象上的動畫效果,可能需要調用View對象上的invalidate()方法,在更新動畫效果時,強制屏幕重繪自己。在onAnimationUpdate()回調方法中做這件事情。例如,一個繪圖對象的顏色屬性的動畫效果,在隊形重繪自己時,才會將變化結果更新到屏幕上。在View對象上的所有的屬性的設置器,如setAlpha()和setTranslationX()會正確的讓View對象失效,因此在調用這些方法設置新的值時候,你不需做失效這件事。有關監聽器的更多信息,請看“動畫監聽器”。
用AnimatorSet類來編排多個動畫
在很多場景中,一個動畫的播放要依賴與另一個動畫的開始或結束。Android系統讓你把這些相互依賴的動畫綁定到一個AnimatorSet對象中,以便能夠指定它們是同時的、順序的、或在指定的延時之後來播放。AnimatorSet對象也能夠彼此嵌套。
以下示例代碼來自Bouncing Balls示例,它按照以下方式播放Animator對象:
1.播放bounceAnim
2.同時播放squashAnim1、squashAnim2、stretchAnim1和stetchAnim2
3.播放bounceBackAnim
4.播放fadeAnim
AnimatorSet bouncer = newAnimatorSet(); bouncer.play(bounceAnim).before(squashAnim1); bouncer.play(squashAnim1).with(squashAnim2); bouncer.play(squashAnim1).with(stretchAnim1); bouncer.play(squashAnim1).with(stretchAnim2); bouncer.play(bounceBackAnim).after(stretchAnim2); ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f); fadeAnim.setDuration(250); AnimatorSet animatorSet = newAnimatorSet(); animatorSet.play(bouncer).before(fadeAnim); animatorSet.start();
關於如何使用動畫集的完整示例,請看APIDemo中的Bouncing Balls示例。
動畫監聽器
使用下列介紹的監聽器能夠監聽動畫播放期間的重要事件:
1.Animator.AnimatorListener
onAnimationStart()---動畫開始的時候被調用
onAnimationEnd()---動畫結束的時候被調用,它不管動畫是如何結束的。
onAnimationRepeate()---動畫重復播放的時候被調用
onAnimationCancel()---動畫被取消播放的時候被調用。
2.ValueAnimator.AnimatorUpdateListener
onAnimationUpdate()---在動畫的幀上調用這個方法。通過監聽這個事件,使用在動畫期間由ValueAnimator對象產生的計算值。要使用這個值,就要用getAnimateValue()方法查詢傳遞到事件中的ValueAnimator對象,以便獲得當前的動畫值。如果使用ValueAnimator類,那麼實現這個監聽器是必須的。
根據屬性或對象的動畫效果,可能需要調用View對象上的invalidate()方法,用新的動畫值來強制屏幕的指定區域進行重繪。例如,Drawable對象的顏色屬性的動畫效果,在對象重繪自己的時候,只會導致屏幕的更新。在View對象上的所有屬性的設置器,如setAlpha()、setTranslationX()等方法都會正確的讓View對象失效,因此在調用這些方法設置新值的時候,你不需要讓該View對象失效。
如果不實現Animator.AnimatorListener接口的所有方法,你能夠繼承AnimatorListenerAdapter類,來代替對Animator.AnimatorListener接口的實現。AnimatorListenerAdapter類對這些方法提供了空的實現,你可以選擇性的重寫這些方法。
例如,APIDemo中的Bouncing Balls示例就只創建了一個AnimatorListenerdapter類的onAnimationEnd()回調方法:
ValueAnimatorAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f); fadeAnim.setDuration(250); fadeAnim.addListener(newAnimatorListenerAdapter() { public void onAnimationEnd(Animator animation) { balls.remove(((ObjectAnimator)animation).getTarget()); }
對於ViewGroups對象布局變化的動畫
屬性動畫系統給ViewGroup對象的動畫變化提供了與View對象一樣容易動畫處理方法。
使用LayoutTransition類在ViewGroup內部處理布局變化的動畫。當調用一個View對象的setVisibility()方法,或者設置該View的GONE常量,或者把該View對象添加到ViewGroup中(或者從ViewGroup中刪除)時,在ViewGroup內部的View對象就能夠實現時隱時現的動畫效果。當在ViewGroup對象中添加或刪除View對象時,其中的其他View對象也能夠動畫移動到新的位置。在LayoutTransition對象內通過調用setAnimator()方法,並且在傳遞給該方法的Animator對象參數中帶有下列LayoutTransition常量之一,就能夠定義該常量所代表的動畫:
1.APPEARING---一個標記,它指示要在容器中正在顯示的項目上運行動畫;
2.CHANGE APPEARING---一個標記,它指示在容器中由於新項目的出現而導致其他項目變化所要運行的動畫;
3.DISAPPEARING---一個標記,它指示一個從容器中消失的項目所要運行的動畫;
4.CHANGE_DISAPPEARING---一個標記,它指示由於一個項目要從容器中消失而導致其他項目的變化,所要運行的動畫。
能夠給這四種事件類型定義自定義動畫,以便定制自己的布局過渡效果,也可以告訴動畫系統只使用默認的動畫效果。
在APIDemo中的LayoutAnimations示例,顯示了如何給布局的過渡定義動畫效果,並且在想要動畫效果的View對象上設置動畫。
LayoutAnimationsByDefault類以及它對應的layout_animations_by_default.xml布局資源文件顯示了如何在XML中啟用ViewGroup對象的默認布局過渡效果。需要做的事情僅僅是把ViewGroup元素的android.animateLayoutchanges屬性設置為true。例如:
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/verticalContainer"
android:animateLayoutChanges="true" />
如果把這個屬性設置為true,那麼在該ViewGroup對象中添加或刪除View對象,以及ViewGroup對象中其他的View對象都會自動的具有動畫效果。
使用TypeEvaluator
如果想要的動畫類型是Android系統所未知的,那麼通過實現TypeEvaluator接口就能夠創建自己的評價器。Android系統已知的類型是int、float或顏色(color),分別有IntEvaluator、FloatEvaluator和ArgbEvaluator類型的評價器所支持。
在TypeEvaluator接口中只有一個要實現的方法:evaluate()方法。這個方法允許正在使用的動畫處理器返回一個適用於於當前動畫時點動畫屬性值,FloatEvaluator類演示了這個方法是如何做這件事的:
public class FloatEvaluator implements TypeEvaluator { public Object evaluate(float fraction, Object startValue, Object endValue) { float startFloat = ((Number) startValue).floatValue(); returnstartFloat + fraction * (((Number) endValue).floatValue() - startFloat); } }
注意:當ValueAnimator對 象(或ObjectAnimator對象)運行時,它會計算當前的動畫播放比例(一個0到1之間的值),然後根據你所使用的插值類型來計算一個要插入的動 畫的版本。插值比例是由TypeEvaluator對象通過fraction參數接收來的,因此在計算動畫值的時候,不需要考慮插值。
使用插補器
插補器定義了怎樣在動畫內指定用於時間函數的計算值。例如,指定貫穿整個動畫期間的線性播放動畫,意味在動畫整個時間裡都是均勻的移動,也能夠指定非線性動畫,如:在動畫的開始或結尾部分使用加速或減速的動畫。
在動畫系統中的插補器會接收一個來自Animator對象的一個比例,它代表了動畫已經過去的時間。插補器修改這個比例,使它與提供的目標動畫類型相吻合。Android系統在android.view.animation包中提供了一組共通的插補器。如果這個包中沒有適合你需要的,你可以實現TimeInterpolator接口來創建自己的插補器。
例如,以下是對AccelerateDecelerateInterpolator和LinearInterpolator插補器如何計算插補比例的比較。LinearInterpolator對延時比例沒有影響,AccelerateDecelerateInterpolator會讓動畫加速進入,並減速退出。以下是這些插補器方法中定義的邏輯:
AccelerateDecelerateInterpolator
public float getInterpolation(float input) { return(float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; }
LinearInterpolator
public float getInterpolation(float input) { returninput; }
下表列出了一個持續1000毫秒的動畫通過插補器所計算的近似值:
播放時間(毫秒)
播放比例/插值比例(線性)
插值比例(加速/減速)
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
1
如上表所示,LinearInterpolator插補器的計算結果是勻速變化的,每200毫秒增加0.2。AccelerateDecelerateInterpolator插補器的計算結果在200毫秒到600毫秒之間比LinearInterpolator的計算結果要快,而在600毫秒到1000毫秒之間則比LinearInterpolator的計算結果要慢。
關鍵幀
有時間和值構成的Keyframe對象會定義動畫在特定的時間點上特定的狀態。每個關鍵幀還有它自己的插補器來控制當前關鍵幀與前一個關鍵幀之間的動畫行為。
要實例化一個Keyframe對象,必須使用以下工廠方法之一:ofInt()、ofFloat()、或ofObject()。使用這些工廠方法來獲取對應類型的關鍵幀,然後調用ofKeyframe工廠方法來獲取一個PropertyValuesHolder對象,一旦獲得了這個對象,就能夠得到一個在PropertyValuesHolder對象中傳遞的動畫制作器對象。以下代碼演示了如何做這件事情:
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);
關於如何使用關鍵幀的完整的示例,情況APIDemo中的MultiPropertyAnimation示例。
http://developer.android.com/tools/samples/index.html
制作View動畫
屬性動畫系統允許對View對象的動畫進行簡化處理,並且在視圖動畫系統上提供了一些優點。視圖動畫系統通過改變View對象的繪制方式來轉換View對象。這種變換是在在每個View對象的容器中來處理的,因為View對象本身沒有執行這種處理的屬性。這種處理會導致View對象產生動畫效果,但卻不會改變View對象自身。這樣即使在屏幕的不同的位置上繪制了View對象,該對象依然會保留在它的原始位置上。在Android3.0中,添加了新的屬性和對象的getter和setter方法,來消除這一缺陷。
屬性動畫系統能夠通過改變View對象中的實際屬性,讓View對象在屏幕上展現動畫效果。另外,View對象也會自動的調用invalidate()方法,在屬性發生變化時來屬性屏幕。在View類中便於動畫設置的新屬性有:
1.translationX和translationY:這兩個屬性作為一種增量來控制著View對象從它布局容器的左上角坐標開始的位置。
2.rotation、rotationX和rotationY:這三個屬性控制View對象圍繞支點進行2D和3D旋轉。
3.scaleX和scaleY:這兩個屬性控制著View對象圍繞它的支點進行2D縮放。
4.pivotX和pivotY:這兩個屬性控制著View對象的支點位置,圍繞這個支點進行旋轉和縮放變換處理。默認情況下,該支點的位置就是View對象的中心點。
5.x和y:這是兩個簡單實用的屬性,它描述了View對象在它的容器中的最終位置,它是最初的左上角坐標和translationX和translationY值的累計和。
6.alpha:它表示View對象的alpha透明度。默認值是1(不透明),0代表完全透明(不可見)。
要讓一個View對象的屬性具有動畫效果,如它的顏色或旋轉值等,就需要創建一個屬性動畫制作器,並給對象屬性指定想要的動畫效果,如:
ObjectAnimator.ofFloat(myView,"rotation",0f,360f);
用ViewPropertyAnimator制作動畫
ViewPropertyAnimator類使用一個單一的Animator對象,給一個View對象的幾個動畫屬性平行處理提供一種簡單的方法。它的行為非常像ObjectAnimator類,因為它修改了View對象屬性的實際的值,但是當多個動畫屬性同時處理時,它會更加高效。另外,使用ViewPropertyAnimator類的代碼更加簡潔和易於閱讀。以下代碼片段顯示了在同時處理View對象的x和y屬性動畫效果時,使用多個ObjectAnimator對象、一個單獨的ObjectAnimator對象和ViewPropertyAnimator對象之間的差異:
多個ObjectAnimator
ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f); AnimatorSet animSetXY = newAnimatorSet(); animSetXY.playTogether(animX, animY); animSetXY.start();
一個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);
在XML中聲明動畫
屬性動畫系統會讓你用XML來聲明屬性動畫,而不是用編程的方式來做它。通過XML中定義你的動畫,能夠更加容易的在多個Activity中重用動畫,並且更加容易的編輯動畫的播放順序。
從Android3.1開始,要把使用新的屬性動畫的API的動畫文件與那些使用傳統的視圖動畫框架區分開,你應該把屬性動畫的XML文件保存在res/animator/目錄中(而不是res/anim/)。animator目錄名是可選的,但是如果想要使用Eclipse ADT插件(ADT11.0.0+)中的布局編輯器,就必須使用animator目錄,因為ADT只搜索res/animator目錄中屬性動畫資源。
以下是屬性動畫類在XML聲明中所使用的對應的XML標簽:
ValueAnimator
-
ObjectAnimator
-
AnimatorSet
-
以下示例順序的播放兩組對象動畫,第一組動畫中嵌套了一個同時播放兩個對象的動畫:
<set android:ordering="sequentially"> <set> <cke:objectanimator android:propertyname="x" android:duration="500" android:valueto="400" android:valuetype="intType"> <cke:objectanimator android:propertyname="y" android:duration="500" android:valueto="300" android:valuetype="intType"> </cke:objectanimator></cke:objectanimator></set> <cke:objectanimator android:propertyname="alpha" android:duration="500" android:valueto="1f"> </cke:objectanimator></set>
為了運行這個動畫,在代碼中,必須把這個XML資源填充到一個AnimatorSet對象中,並且在開始播放這個動畫集之前,要把這個動畫集合設置給目標對象。調用setTarget()方法就可以方便的把AnimatorSet對象中的所有子對象設置給一個單一的目標對象。以下代碼顯示了做這件事的方法:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();
如何用Sencha Touch打包Android的APK 什麼是Sencha Touch 前不久基於JavaScript編寫的Ajax框架ExtJS,將現有的ExtJ
【React Native開發】React Native控件之ProgressBarAndroid進度條講解(12) (一)前言 今天我們一起來看一下進度加載條Pro
Android中Fragment的兩種創建方式,androidfragmentfragment是Activity中用戶界面的一個行為或者是一部分。你可以在一個單獨的Act
QQ空間實現(一)—— 展示說說中的評論內容並有相應點擊事件,評論內容事件大家都玩QQ空間客戶端,對於每一個說說,我們都可以評論,那麼,對於某一條評論: 白雪公主 回復