每個人都有一定的理想,這種理想決定著他的努力和判斷的方向。就在這個意義上,我從來不把安逸和快樂看作生活目的的本身——這種倫理基礎,我叫它豬欄的理想。——愛因斯坦
如果大家想看更多關於Android基礎夯實系列博文,請移步到我的部落格:
Ryane's Blog
一、摘要
Property Animation(屬性動畫)是一個非常強大的框架,它允許你讓任何物件都實現動畫效果。 因為不管一個物件是否出現螢幕中,你都可以隨時去改變它的屬性,而屬性動畫正是通過在某個時間點改變物件的屬性實現動畫效果的。Property Animation是在Android 3.0(API 11)之後推出的,以其具有高擴充套件性,解決了一些View Animation所不能解決的問題,所以,對於Android開發者來說,Property Animation是一個非常重要的知識點。
本文主要對ValueAnimator做介紹,如果大家有興趣,可以繼續閱讀本動畫系列其他相關文章,作者也在不斷更新完善相關內容,希望大家可以指出有誤之處。
Android基礎夯實--重溫動畫(一)之Tween Animation
Android基礎夯實--重溫動畫(二)之Frame Animation
Android基礎夯實--重溫動畫(四)之屬性動畫 ValueAnimator詳解
1.1 背景
由於Tween Animation(補間動畫)只能實現簡單的四種的動畫(alpha、scale、rotate、translate),要想實現比較複雜的動畫就難以滿足需求,而Frame Animation只是改變了View物件繪製的背景,而沒有改變View物件本身。所以當我們想使用View Animation實現一些特殊的動畫效果時,就比較困難了。例如,當我們想改變一個控制元件的背景顏色時,檢視動畫並不能實現;當我們想設定一個按鈕在位置轉換之後,仍然保持點選事件,檢視動畫也不能實現。在這個背景之下,屬性動畫應運而生。
1.2 區別
說了這麼多,那麼檢視動畫和屬性動畫到底有什麼區別呢?
首先,在直觀上,屬性動畫是區別於檢視動畫的:
(1) 時間不一樣: 檢視動畫是從API LEVEL 1就引入了;而屬性動畫是從API LEVEL 11之後才引入。
(2) 名字不一樣: 檢視動畫的Tween Animation命名為xxxAnimation、Frame Animation命名為AnimationDrawable;而屬性動畫,則命名為xxxAnimator。
(3) 包名不一樣: 檢視動畫的Tween Animation在包android.view.animation下,而Property Animation在包android.animation中。
其次,從根本上,我們可以總結出檢視動畫和屬性動畫的兩個主要區別:
(1) 檢視動畫只能改變View的位置或者視覺效果,並不能改變其屬性。例如:使用Tween Animation對Button實現位移變換後位置改變,但是點選Button最後停留位置時,並不能響應點選事件。怎麼理解呢,舉個例子:
由上圖可知,我們給TextView設定了點選事件,當我們分別使用Tween Animation和Property Animation移動TextView時,當使用Tween Animation位移TextView後,它的點選事件無效,當使用Property Animation移動TextView後,它的點選事件仍然有效。由此可見,檢視動畫並不能改變View的屬性,而屬性動畫可以。
(2) 檢視動畫作用物件只限製為View,而屬性動畫作用物件不限為View,而是任何物件。例如:屬性動畫可以改變顏色值而檢視動畫做不到。同樣舉個例子:
由上圖可以看到,當我們需要對一個物件的顏色值進行改變時,檢視動畫並不能實現這個效果,上圖是通過屬性動畫來實現的,由此可以推測出,檢視動畫只能對View起作用,而屬性動畫作用的不只是View,而是物件。
1.3 建議
雖然Property Animation的優點要多於View Animation,但是View Animaiton可以讓我們花更少的時間和更少的程式碼去實現,所以如果View Animation已經足以滿足我們的日常需要,那麼我們就沒必要使用Property Animation了,當然,如果我們都涉及到的話,同時使用View Animation和Property Animation可能是更有效的辦法。
如果你想了解更權威的解釋,可以檢視官方文件:Property Animation。
本文主要對Property Animation做介紹,如果大家有興趣,可以繼續閱讀本動畫系列其他相關文章:
Android基礎夯實--重溫動畫(一)之Tween Animation
Android基礎夯實--重溫動畫(二)之Frame Animation
二、工作原理
在講述具體Property Animation相關API之前,我想先給大家講一下屬性動畫是如何工作的。下面通過一個例子,這是Android開發指南上面的一個例子,我覺得非常好理解,這裡就搬過來了。
首先,我們來看一個例子。如下圖描述的是一個物件在它的x方向上進行水平運動的動畫(規定右方向為正軸),當然我們可以對應成手機螢幕上的位置。這個動畫的時長為40ms,物件在x正方向運動了40個畫素,在每個10ms內,這個物件就往x正方向運動10個畫素,在第40ms時,這個動畫停在了x方向上的40畫素,這是一個水平勻速運動的例子。
當然,我們也可以給動畫定義一個具有不勻速插值器(Interpolation),是它運動過程為不勻速。
如下圖也是一個物件的運動過程,但是它並不是勻速運動,而是開始加速,在結束前減速。這個物件仍然是在40秒內運動了40個畫素的距離,但是這個過程是不勻速的,它從開始到中間位置進行了加速運動,在中間位置到結束位置則進行了減速運動。
從上面兩個例子可以看到,當我們想要一個物件實現一定的動畫效果時,我們可以通過對應的圖,還有相關的資料,和相關資料伴隨時間的變化來描述該動畫過程,但是我們的屬性動畫的內部是如何像我們這樣來描述自身的變化過程的呢?以ValueAnimator為例,我們來看一下屬性動畫的重要組成部分,如下圖所示。
ValueAnimator是屬性動畫最基礎的一個類(我們暫且不深究它,反正它能幫助我們實現圖2的先加速後減速的過程)。首先它在內部封裝了非常重要的兩個介面,第一個就是TimeInterpolator,另一個是TypeEvaluator。大家在心裡必須先有個概念,在所有的屬性動畫裡面,都擁有這兩個東西。
TimeInterpolator是什麼呢?非常簡單,就是我們上面所說的插值器,簡單來說就是描述物件加速度的一個東西,再簡單一點來說就是描述速度變化的一個東西。
TypeEvaluator又是什麼呢?大家可以理解為求值器,它是根據上面的插值器來計算物件屬性具體值的這麼一個東西。
ValueAnimator在執行之前,首先會把時間分為百分數,由0~1,如上圖動畫過程為40ms,那麼在10ms時,時間因子為0.25,在40ms時,時間因子為1。
在計算完時間因子之後,ValueAnimator會呼叫TimeInterpolator來進行計算插值因子,在圖2對應為速度,對應10ms時的速度我們知道會比20ms時的速度會低;而圖1中,每一個時刻的速度都一樣,所以TimeInterpolator大概是做這麼一件事情。
在TimeInterpolator計算完了之後,那麼我們的TypeEvaluator就要起作用了,因為上圖對應的是物件的位置變化,所以TypeEvaluator為IntEvaluator。這個TypeEvaluator主要是根據TimeInterpolator提供的插值因子(速度),還有startPropertyValue(開始時間)和endPropertyValue(結束時間),計算出某個時刻的屬性值(位移),如圖2,假如t=10ms時刻,TimeInterpolator給我們返回值為0.15,那麼這時在x方向上的位移為0.15 * (40 - 0) = 6。
而這種計算過程在動畫執行時間(duration)內是不斷重複的,因為ValueAnimator有一個叫做AnimatorUpdateListener的監聽器,它會跟蹤動畫的每一個時刻,所以我們可以在裡面進行不斷的計算,通過getAnimatedValue()來獲取最新值,直到動畫結束。
一個屬性動畫的執行過程大概如上,相信大家已經對屬性動畫有了基本的瞭解,那麼我們下面根據API來對屬性動畫進行詳細講解。
三、API概況
前面我們說到,屬性動畫機制所有相關的類都位於android.animation包之下,所以大家有需要可以到官方文件中進行查閱。下面幾個表格是屬性動畫中常用的類,首先給大家大概介紹。
表格1. Animators
Class | Description |
---|---|
ValueAnimator | 針對值變化的Animator。 |
ObjectAnimator | 針對Object變化的Animator。 |
AnimatorSet | 執行一組Animator的集合。 |
Animator類作為屬性動畫的基類,它是一個抽象類,它提供了實現動畫的基本架構,但是我們不能直接使用它,因為它只是提供了最基本的的實現動畫的方法,只有讓它的子類繼承它並進行相應擴充套件之後,我們才會使用它實現動畫。在屬性動畫中,Animator包括了ValueAnimator、ObjectAnimator和AnimatorSet三個子類,我們分別來介紹一下這三個類。
表格2. Evaluators
Class | Description |
---|---|
TypeEvaluator | 求值器介面,所有求值器必須實現該介面。 |
IntEvaluator | 計算Int型別的求值器。 |
FloatEvaluator | 計算Float型別的求值器。 |
ArgbEvaluator | 計算顏色值型別的求值器。 |
API中為我們提供了求值器的介面TypeEvaluator,當然還要它的實現類,例如IntEvaluator、FloatEvaluator、ArgbEvaluator、 IntArrayEvaluator、FloatArrayEvaluator等,它們都是根據fraction因子來計算出對應的屬性值,當然我們也可以自定義自己的Evaluator。
表格3. Interpolators
Class | Description |
---|---|
TimeInterpolator | Animator的插值器介面。 |
TimeInterpolator作為屬性動畫的插值器介面,我們都知道在View Animation中有很多插值器,例如AccelerateDecelerateInterpolator(前後減速,中間加速)、AccelerateInterpolator(先慢後加速)等插值器,在屬性動畫中我們同樣可以使用這些插值器,這裡就不詳細列出來了,不瞭解的同學可以看我之前的文章:Android基礎夯實--重溫動畫(一)之Tween Animation。當然,我們也可以自定義自己的Interpolator。
四、結語
由於文章篇幅過長,不利於大家閱讀,所以這篇文章首先給大家介紹屬性動畫這個概念,相信通過例子和文字的介紹,大家也已經對屬性動畫有所瞭解,那麼接下來,我就會給大家詳細講解屬性動畫中的每一個知識點,當然,也會分多篇文章進行分析,如果你已經準備好,請繼續閱讀Android基礎夯實--重溫動畫(四)之屬性動畫 ValueAnimator詳解。