一: 傳統(tǒng) View 動(dòng)畫(huà)(Tween/Frame)
1.1 Tween 動(dòng)畫(huà)
主要有 4 中:縮放、平移、漸變、旋轉(zhuǎn)

文件位置: res/anim/filename.xml
編譯資源的數(shù)據(jù)類(lèi)型:an Animation
資源引用:
Java: R.anim.filename
XML: @[package:]anim/filename

布局文件必須有一個(gè)獨(dú)立的根元素,可以是?,,?,?,?(持有一組其它的動(dòng)畫(huà)元素,甚至可以是內(nèi)嵌的 set 元素) 中的一個(gè)
1.1.1?
一個(gè)持有其它動(dòng)畫(huà)元素的容器?,?,?,或者其它??元素
屬性
android:interpolator
應(yīng)用于動(dòng)畫(huà)的插值器。該值必須是一個(gè)指定了插值器資源的引用(不是一個(gè)插值器的類(lèi)名),在平臺(tái)中有缺省的插值器資源可以使用,或者你可以創(chuàng)建自己的插值器資源,可以看下面關(guān)于插值器的討論。
android:shareInterpolator
Boolean 值, true:代表在所有的子元素中共享同一個(gè)插值器
1.1.2?
A fade-in or fade-out animation. Represents an AlphaAnimation. 一個(gè)漸入漸出的動(dòng)畫(huà),對(duì)應(yīng)的 java 類(lèi)為 AlphaAnimation。
屬性
android:fromAlpha
android:toAlpha
代表動(dòng)畫(huà)開(kāi)始和結(jié)束時(shí)透明度,0.0 表示完全透明,1.0 表示完全不透明,F(xiàn)loat 值
1.1.3?
可以實(shí)現(xiàn)動(dòng)態(tài)調(diào)控件尺寸的效果,通過(guò)設(shè)置 pivotX 和 pivotY 你可以指定 image 縮放的中心點(diǎn),比如:如果這些值是 0,則表示左上角,所有的縮放變化將沿著右下角的軌跡運(yùn)動(dòng)。對(duì)應(yīng)的類(lèi)為:ScaleAnimation
屬性
android:fromXScale
android:toXScale
android:fromYScale
android:toYScale
Float 值,為動(dòng)畫(huà)起始到結(jié)束時(shí),X、Y 坐標(biāo)上的伸縮尺寸
0.0 表示收縮到?jīng)]有
1.0 表示正常無(wú)伸縮
android:pivotX
android:pivotY
代表縮放的中軸點(diǎn) X/Y 坐標(biāo),浮點(diǎn)值
如果我們想表示中軸點(diǎn)為圖像的中心,我們可以把兩個(gè)屬性值定義成 0.5 或者 50%。
1.1.4?
代表一個(gè)水平、垂直的位移。對(duì)應(yīng)的類(lèi)為 TranslateAnimation. 屬性
android:fromXDelta 屬性代表起始 X 方向的位置
android:toXDelta
android:fromYDelta
android:toYDelta
代表動(dòng)畫(huà)起始或者結(jié)束 X / Y 方向上的位置,F(xiàn)loat 或者百分比值
浮點(diǎn)數(shù) num%、num%p 分別相對(duì)于自身或者父控件
如果以浮點(diǎn)數(shù)字表示,是一個(gè)絕對(duì)值,代表相對(duì)自身原始位置的像素值;
如果以 num%表示,代表相對(duì)于自己的百分比,比如 toXDelta 定義為 100%就表示在 X 方向上移動(dòng)自己的 1 倍距離
如果以 num%p 表示,代表相對(duì)于父類(lèi)組件的百分比。
1.1.5?
是旋轉(zhuǎn)動(dòng)畫(huà),與之對(duì)應(yīng)的 Java 類(lèi)是 RotateAnimation
屬性
android:fromDegrees
android:toDegrees
代表起始和結(jié)束的角度,浮點(diǎn)值,單位:度
android:pivotX 屬性代表旋轉(zhuǎn)中心的 X 坐標(biāo)值
android:pivotY 屬性代表旋轉(zhuǎn)中心的 Y 坐標(biāo)值
Float 值或者百分比
這兩個(gè)屬性也有三種表示方式,但是 X 軸都是相對(duì)方向都是 Left,Y 軸都是相對(duì)于 Top
浮點(diǎn)數(shù)、num%、num%p;
數(shù)字方式代表相對(duì)于自身左邊緣的像素值,
num%方式代表相對(duì)于自身左邊緣或頂邊緣的百分比,
num%p 方式代表相對(duì)于父容器的左邊緣或頂邊緣的百分比
屬性
android:fromDegrees
android:toDegrees
開(kāi)始和結(jié)束時(shí)的弧度位置,單位是度,F(xiàn)loat 值
調(diào)用代碼

另外,在動(dòng)畫(huà)中,如果我們添加了 android:fillAfter="true"后,這個(gè)動(dòng)畫(huà)執(zhí)行完之后保持最后的狀態(tài);android:duration="integer"代表動(dòng)畫(huà)持續(xù)的時(shí)間,單位為毫秒。
1.1.6 插值器
用于修改一個(gè)動(dòng)畫(huà)過(guò)程中的速率,可以定義各種各樣的非線(xiàn)性變化函數(shù),比如加速、減速等
在 Android 中所有的插值器都是 Interpolator 的子類(lèi),通過(guò) android:interpolator 屬性你可以引用不同的插值器。下面是幾種插值器:

你可以通過(guò)下面的方式使用它們:

自定義插值器?如果你對(duì)系統(tǒng)提供的插值器不滿(mǎn)意,我們可以創(chuàng)建一個(gè)插值器資源修改插值器的屬性,比如修改 AnticipateInterpolator 的加速速率,調(diào)整 CycleInterpolator 的循環(huán)次數(shù)等。為了完成這種需求,我們需要?jiǎng)?chuàng)建 XML 資源文件,然后將其放于/res/anim 下,然后再動(dòng)畫(huà)元素中引用即可。我們先來(lái)看一下幾種常見(jiàn)的插值器可調(diào)整的屬性:

我們先來(lái)看一下幾種常見(jiàn)的插值器可調(diào)整的屬性:
<accelerateDecelerateInterpolator> 無(wú)
?<accelerateInterpolator> android:factor 浮點(diǎn)值,加速速率,默認(rèn)為 1
?<anticipateInterploator> android:tension 浮點(diǎn)值,起始點(diǎn)后退的張力、拉力數(shù),默認(rèn)為 2
?<anticipateOvershootInterpolator> android:tension 同上 android:extraTension 浮點(diǎn)值,拉力的倍數(shù),默認(rèn)為 1.5(2 * 1.5)
?<bounceInterpolator> 無(wú)
?<cycleInterplolator> android:cycles int,循環(huán)的個(gè)數(shù),默認(rèn)為 1
?<decelerateInterpolator> android:factor 浮點(diǎn)值,減速的速率,默認(rèn)為 1
?<linearInterpolator> 無(wú)
?<overshootInterpolator> 浮點(diǎn)值,超出終點(diǎn)后的張力、拉力,默認(rèn)為 2
比如:res/anim/my_overshoot_interpolator.xml:

如果簡(jiǎn)單的修改插值器的屬性值還不能夠滿(mǎn)足我們的需求,那么就自己來(lái)通過(guò)實(shí)現(xiàn) Interpolator 接口來(lái)定義自己的插值器了 因?yàn)樯厦嫠械?Interpolator 都實(shí)現(xiàn)了 Interpolator 接口,這個(gè)接口定義了一個(gè)方法:float getInterpolation(float input); 此方法由系統(tǒng)調(diào)用,input 代表動(dòng)畫(huà)的時(shí)間,在 0 和 1 之間,也就是開(kāi)始和結(jié)束之間。
線(xiàn)性(勻速)插值器定義如下:

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

1.2 Frame 動(dòng)畫(huà)
文件目錄:res/drawable/filename.xml
編譯資源數(shù)據(jù)類(lèi)型 AnimationDrawable
資源引用:
Java: R.drawable.filename
XML: @[package:]drawable.filename

1.2.1?
必須作為根元素,包含一個(gè)或者多個(gè)根元素
屬性:android:oneshot :true:只執(zhí)行一次動(dòng)畫(huà),false:循環(huán)執(zhí)行
1.2.2?
A single frame of animation. Must be a child of a??element. 一幀獨(dú)立動(dòng)畫(huà),必須是?的子元素
屬性
android:drawable
Drawable 資源,用于這一幀的圖片
android:duration
Integer 類(lèi)型.該幀的時(shí)長(zhǎng),單位為毫秒 milliseconds.
res/anim/rocket.xml:

調(diào)用代碼:

二. Property Animation
2.1 Property Animation 的工作方式
Property Animation 動(dòng)畫(huà)有兩個(gè)步聚:
1.計(jì)算屬性值
2.為目標(biāo)對(duì)象的屬性設(shè)置屬性值,即應(yīng)用和刷新動(dòng)畫(huà)
2.1.1 計(jì)算屬性值

過(guò)程一:計(jì)算已完成動(dòng)畫(huà)分?jǐn)?shù) elapsed fraction?為了執(zhí)行一個(gè)動(dòng)畫(huà),你需要?jiǎng)?chuàng)建一個(gè) ValueAnimator,并且指定目標(biāo)對(duì)象屬性的開(kāi)始、結(jié)束值和持續(xù)時(shí)間。在調(diào)用 start 后的整個(gè)動(dòng)畫(huà)過(guò)程中, ValueAnimator 會(huì)根據(jù)已經(jīng)完成的動(dòng)畫(huà)時(shí)間計(jì)算得到一個(gè) 0 到 1 之間的分?jǐn)?shù),代表該動(dòng)畫(huà)的已完成動(dòng)畫(huà)百分比。0 表示 0%,1 表示 100%。
過(guò)程二:計(jì)算插值(動(dòng)畫(huà)變化率)interpolated fraction?當(dāng) ValueAnimator 計(jì)算完已完成動(dòng)畫(huà)分?jǐn)?shù)后,它會(huì)調(diào)用當(dāng)前設(shè)置的 TimeInterpolator,去計(jì)算得到一個(gè) interpolated(插值)分?jǐn)?shù),在計(jì)算過(guò)程中,已完成動(dòng)畫(huà)百分比會(huì)被加入到新的插值計(jì)算中。
過(guò)程三:計(jì)算屬性值?當(dāng)插值分?jǐn)?shù)計(jì)算完成后,ValueAnimator 會(huì)根據(jù)插值分?jǐn)?shù)調(diào)用合適的 TypeEvaluator 去計(jì)算運(yùn)動(dòng)中的屬性值。
以上分析引入了兩個(gè)概念:已完成動(dòng)畫(huà)分?jǐn)?shù)(elapsed fraction)、插值分?jǐn)?shù)( interpolated fraction )。
2.2 核心類(lèi)

2.2.1 Interpolators
插值器:時(shí)間的函數(shù),定義了動(dòng)畫(huà)的變化律。
插值器只需實(shí)現(xiàn)一個(gè)方法:getInterpolation(float input),其作用就是把 0 到 1 的 elapsed fraction 變化映射到另一個(gè) interpolated fraction。 Interpolator 接口的直接繼承自TimeInterpolator,內(nèi)部沒(méi)有任何方法,而TimeInterpolator只有一個(gè)getInterpolation方法,所以所有的插值器只需實(shí)現(xiàn)getInterpolation方法即可。
傳入?yún)?shù)是正常執(zhí)行動(dòng)畫(huà)的時(shí)間點(diǎn),返回值是調(diào)用者真正想要它執(zhí)行的時(shí)間點(diǎn)。傳入?yún)?shù)是{0,1},返回值一般也是{0,1}。{0,1}表示整段動(dòng)畫(huà)的過(guò)程。中間的 0.2、0.3 等小數(shù)表示在整個(gè)動(dòng)畫(huà)(原本是勻速的)中的位置,其實(shí)就是一個(gè)比值。如果返回值是負(fù)數(shù),會(huì)沿著相反的方向執(zhí)行。如果返回的是大于 1,會(huì)超出正方向執(zhí)行。也就是說(shuō),動(dòng)畫(huà)可能在你指定的值上下波動(dòng),大多數(shù)情況下是在指定值的范圍內(nèi)。
getInterpolation(float input)改變了默認(rèn)動(dòng)畫(huà)的時(shí)間點(diǎn) elapsed fraction,根據(jù)時(shí)間點(diǎn) interpolated fraction 得到的是與默認(rèn)時(shí)間點(diǎn)不同的屬性值,插值器的原理就是通過(guò)改變實(shí)際執(zhí)行動(dòng)畫(huà)的時(shí)間點(diǎn),提前或延遲默認(rèn)動(dòng)畫(huà)的時(shí)間點(diǎn)來(lái)達(dá)到加速/減速的效果。動(dòng)畫(huà)插值器目前都只是對(duì)動(dòng)畫(huà)執(zhí)行過(guò)程的時(shí)間進(jìn)行修飾,并沒(méi)有對(duì)軌跡進(jìn)行修飾。
簡(jiǎn)單點(diǎn)解釋這個(gè)方法,就是當(dāng)要執(zhí)行 input 的時(shí)間時(shí),通過(guò) Interpolator 計(jì)算返回另外一個(gè)時(shí)間點(diǎn),讓系統(tǒng)執(zhí)行另外一個(gè)時(shí)間的動(dòng)畫(huà)效果。
2.2.2 Evaluators
Evaluators 告訴屬性動(dòng)畫(huà)系統(tǒng)如何去計(jì)算一個(gè)屬性值。它們通過(guò) Animator 提供的動(dòng)畫(huà)的起始和結(jié)束值去計(jì)算一個(gè)動(dòng)畫(huà)的屬性值。 屬性系統(tǒng)提供了以下幾種 Evaluators: 1.IntEvaluator
2.FloatEvaluator
3.ArgbEvaluator
這三個(gè)由系統(tǒng)提供,分別用于計(jì)算 int,float,color 型(十六進(jìn)制)屬性的計(jì)算器
4.TypeEvaluator
一個(gè)用于用戶(hù)自定義計(jì)算器的接口,如果你的對(duì)象屬性值類(lèi)型,不是 int,float,或者 color 類(lèi)型,你必須實(shí)現(xiàn)這個(gè)接口,去定義自己的數(shù)據(jù)類(lèi)型。
TypeEvaluator接口只有一個(gè)方法,就是evaluate()方法,它允許你使用的 animator 返回一個(gè)當(dāng)前動(dòng)畫(huà)點(diǎn)的屬性值。
TimeInterpolator 和 TypeEvaluator 的區(qū)別
首先明確動(dòng)畫(huà)屬性值的計(jì)算包括三步,其中第二步和第三步分別需要借助TimeInterpolator和TypeEvluator完成。
TypeEvaluator所做的是根據(jù)數(shù)據(jù)結(jié)構(gòu)計(jì)算最終的屬性值,允許你定義自己的數(shù)據(jù)結(jié)構(gòu),這是官方對(duì)它的真正定義,如果你所定義的屬性值的數(shù)據(jù)類(lèi)型不是 float、int、color 類(lèi)型,那么你需要實(shí)現(xiàn) TypeEvaluator 接口的evaluate()方法,自己進(jìn)行屬性值的計(jì)算
Interpolator更傾向于你定義一種運(yùn)動(dòng)的變化率,比如勻速、加速、減速等,官方對(duì) Interpolator 的定義也確實(shí)是這樣的:
A time interpolator defines the rate of change of an >animation. This allows animations to have non-linear >motion, such as acceleration and deceleration.
對(duì)于自定義高級(jí)動(dòng)畫(huà)時(shí),弄清TimeInterpolator和TypeEvaluator非常重要,如果你希望要自定義自己的動(dòng)畫(huà),那么這兩個(gè)函數(shù)肯定是關(guān)鍵部分,一個(gè)是定義動(dòng)畫(huà)變化率,一個(gè)是定義數(shù)據(jù)結(jié)構(gòu)和屬性值計(jì)算方式,兩者共同決定了一個(gè)動(dòng)畫(huà)的運(yùn)動(dòng)。
2.2.3 ValueAnimator
屬性動(dòng)畫(huà)中的主要的時(shí)序引擎,如動(dòng)畫(huà)時(shí)間,開(kāi)始、結(jié)束屬性值,相應(yīng)時(shí)間屬性值計(jì)算方法等。包含了所有計(jì)算動(dòng)畫(huà)值的核心函數(shù)。也包含了每一個(gè)動(dòng)畫(huà)時(shí)間上的細(xì)節(jié),信息,一個(gè)動(dòng)畫(huà)是否重復(fù),是否監(jiān)聽(tīng)更新事件等,并且還可以設(shè)置自定義的計(jì)算類(lèi)型。
使用 ValueAnimator 實(shí)現(xiàn)動(dòng)畫(huà)需要手動(dòng)更新:

2.2.4 ObjectAnimator
繼承自ValueAnimator,允許你指定要進(jìn)行動(dòng)畫(huà)的對(duì)象以及該對(duì)象的一個(gè)屬性。該類(lèi)會(huì)根據(jù)計(jì)算得到的新值自動(dòng)更新屬性。也就是說(shuō)上 Property Animation 的兩個(gè)步驟都實(shí)現(xiàn)了。大多數(shù)的情況,你使用ObjectAnimator就足夠了,因?yàn)樗沟媚繕?biāo)對(duì)象動(dòng)畫(huà)值的處理過(guò)程變得簡(jiǎn)單,不用再向ValueAnimator那樣自己寫(xiě)動(dòng)畫(huà)更新的邏輯。但ObjectAnimator有一定的限制,比如它需要目標(biāo)對(duì)象的屬性提供指定的處理方法,這個(gè)時(shí)候你需要根據(jù)自己的需求在ObjectAnimator和ValueAnimator中做個(gè)選擇了,看哪種實(shí)現(xiàn)更簡(jiǎn)便。
ObjectAnimator的自動(dòng)更新功能,依賴(lài)于屬性身上的setter和getter方法,所以為了讓ObjectAnimator能夠正確的更新屬性值,你必須遵從以下規(guī)范:
1.該對(duì)象的屬性必須有g(shù)et和set方法(方法的格式必須是駝峰式),方法格式為 set(),因?yàn)?ObjectAnimator 會(huì)自動(dòng)更新屬性,它必須能夠訪(fǎng)問(wèn)到屬性的setter方法,比如屬性名為foo,你就需要一個(gè)setFoo()方法,如果 setter 方法不存在,你有三種選擇:
a.添加 setter 方法
b.使用包裝類(lèi)。通過(guò)該包裝類(lèi)通過(guò)一個(gè)有效的 setter 方法獲取或者改變屬性值的方法,然后應(yīng)用于原始對(duì)象,比如 NOA 的AnimatorProxy。
c.使用 ValueAnimator 代替
(這 3 點(diǎn)的意思總結(jié)起來(lái)就是一定要有一個(gè)setter方法,讓ObjectAnimator能夠訪(fǎng)問(wèn)到)
1.如果你為 ObjectAnimator 的工廠(chǎng)方法的可變參數(shù)只傳遞了一個(gè)值,那么會(huì)被作為動(dòng)畫(huà)的結(jié)束值。
2.注意,屬性的getter方法和setter方法必須必須是相對(duì)應(yīng)的,比如你構(gòu)造了一個(gè)如下的ObjectAnimator,那么getter和setter方法就應(yīng)該為:

3.根據(jù)動(dòng)畫(huà)的目標(biāo)屬性或者對(duì)象不同,你可能需要調(diào)用某一個(gè) View 的invalidate方法,根據(jù)新的動(dòng)畫(huà)值去強(qiáng)制屏幕重繪該 View。可以在onAnimateonUpdate()回調(diào)方法中去做。比如,對(duì)一個(gè) Drawable 的顏色屬性進(jìn)行動(dòng)畫(huà),只有當(dāng)對(duì)象重繪自身的時(shí)候,才會(huì)導(dǎo)致該屬性的更新,(不像平移或者縮放那樣是實(shí)時(shí)的)。一個(gè) View 的所有 setter 屬性方法,比如setAlpha()和setTranslationX()都可以適當(dāng)?shù)母?View。因此你不需要在重繪的時(shí)候?yàn)檫@些方法傳遞新的值。更多關(guān)于 Listener 的信息,可以參考第四部分 Animation Listeners。
簡(jiǎn)單總結(jié)下:?當(dāng)你不希望向外暴露Setter方法的時(shí)候,或者希望獲取到動(dòng)畫(huà)值統(tǒng)一做處理的話(huà),亦或只需要一個(gè)簡(jiǎn)單的時(shí)序機(jī)制(擁有動(dòng)畫(huà)的各種值)的話(huà),那么你可以選擇使用ValueAnimator,它更簡(jiǎn)單。如果你就是希望更新動(dòng)畫(huà),為了簡(jiǎn)便,可以使用ObjectAnimator,但自定義的屬性必須有setter和getter方法,并且它們必須都是標(biāo)準(zhǔn)的駝峰式(確保內(nèi)部能夠調(diào)用),必須有結(jié)束值。你可以實(shí)現(xiàn)Animator.AnimatorListener接口根據(jù)自己的需求去更新 View。
2.2.5 AnimatorSet
提供組合動(dòng)畫(huà)能力的類(lèi)。并可設(shè)置組中動(dòng)畫(huà)的時(shí)序關(guān)系,如同時(shí)播放、有序播放或延遲播放。Elevator會(huì)告訴屬性動(dòng)畫(huà)系統(tǒng)如何計(jì)算一個(gè)屬性的值,它們會(huì)從Animator類(lèi)中獲取時(shí)序數(shù)據(jù),比如開(kāi)始和結(jié)束值,并依據(jù)這些數(shù)據(jù)計(jì)算動(dòng)畫(huà)的屬性值。
小結(jié):?TypeEvaluator
定義了屬性值的計(jì)算方式,有 int,float,color 類(lèi)型,根據(jù)屬性的開(kāi)始、結(jié)束值和插值一起計(jì)算出當(dāng)前時(shí)間的屬性值,終極方法,整個(gè)動(dòng)畫(huà)屬性值計(jì)算過(guò)程的結(jié)尾。
TimeInterpolation
插值器都必須實(shí)現(xiàn)的接口,定義了動(dòng)畫(huà)的變化率,如線(xiàn)性,非線(xiàn)性。
ValueAnimator與ObjectAnimator:
兩者都可以進(jìn)行屬性動(dòng)畫(huà),但是ObjectAnimator更加簡(jiǎn)單,不用去做更新屬性值的計(jì)算,但是必須要提供標(biāo)準(zhǔn)的setter和getter方法,讓ObjectAnimator能夠獲取和更新屬性值。
2.2.6 ViewPropertyAnimator
可以方便的為某個(gè) View 的多個(gè)屬性添加并行的動(dòng)畫(huà),只使用一個(gè)ViewPropertyAnimator對(duì)象就可以完成。它的行為更像一個(gè)ObjectAnimator,因?yàn)樗薷牡氖菍?duì)象的實(shí)際屬性值。但它為一次性給多個(gè)屬性添加動(dòng)畫(huà)提供了方便,而且使用ViewPropertyAnimator的代碼更連貫更易讀。
下面的代碼段分別展示了使用多個(gè)ObjectAnimator對(duì)象、一個(gè)ObjectAnimator對(duì)象、?ViewPropertyAnimator同時(shí)為一個(gè) View 的 X 和 Y 屬性添加動(dòng)畫(huà)的示例:
多個(gè) ObjectAnimator 結(jié)合 AnimatorSet 實(shí)現(xiàn)

一個(gè) ObjectAnimator 結(jié)合多個(gè) PropertyValuesHolder 實(shí)現(xiàn)

ViewPropertyAnimator: 只需一行代碼
myView.animate().x(50f).y(100f);//myView.animate()直接返回一個(gè) ViewPropertyAnimator 對(duì)象
2.2.7 PropertyValuesHolder
顧名思義,該類(lèi)持有屬性,相關(guān)屬性值的操作以及屬性的 setter,getter 方法的創(chuàng)建,屬性值以 Keyframe 來(lái)承載,最終由 KeyframeSet 統(tǒng)一處理。
2.2.8 KeyFrame
一個(gè)keyframe對(duì)象由一對(duì) time / value 的鍵值對(duì)組成,可以為動(dòng)畫(huà)定義某一特定時(shí)間的特定狀態(tài)。
每個(gè)keyframe可以擁有自己的插值器,用于控制前一幀和當(dāng)前幀的時(shí)間間隔間內(nèi)的動(dòng)畫(huà)。
Keyframe.ofFloat(0f,0f);?第一個(gè)參數(shù)為:要執(zhí)行該幀動(dòng)畫(huà)的時(shí)間節(jié)點(diǎn)(elapsed time / duration)
第二個(gè)參數(shù)為屬性值。
因此如果你想指定某一特定時(shí)間的特定狀態(tài),那么簡(jiǎn)單的使用 ObjectAnimator就滿(mǎn)足不了你了,因?yàn)?,ObjectAnimator.ofInt(....)類(lèi)似的工廠(chǎng)方法,無(wú)法指定特定的時(shí)間點(diǎn)的狀態(tài)。
每個(gè) KeyFrame 的 Interpolator
每個(gè)KeyFrame其實(shí)也有個(gè)Interpolator。如果沒(méi)有設(shè)置,默認(rèn)是線(xiàn)性的。之前為Animator設(shè)置的Interpolator是整個(gè)動(dòng)畫(huà)的,而系統(tǒng)允許你為每一KeyFrame的單獨(dú)定義Interpolator,系統(tǒng)這樣做的目的是允許你在某一個(gè)keyFrame做特殊的處理,也就是整體上是按照你的插值函數(shù)來(lái)計(jì)算,但是,如果你希望某個(gè)或某些KeyFrame會(huì)有不同的動(dòng)畫(huà)表現(xiàn),那么你可以為這個(gè)keyFrame設(shè)置Interpolator。
因此,Keyframe 的定制性更高,你如果想精確控制某一個(gè)時(shí)間點(diǎn)的動(dòng)畫(huà)值及其運(yùn)動(dòng)規(guī)律,你可以自己創(chuàng)建特定的 Keyframe
Keyframe 使用
為了實(shí)例化一個(gè)keyframe對(duì)象,你必須使用某一個(gè)工廠(chǎng)方法:ofInt(), ofFloat(), or ofObject() 去獲取合適的keyframe類(lèi)型,然后你調(diào)用ofKeyframe工廠(chǎng)方法去獲取一個(gè)PropertyValuesHolder對(duì)象,一旦你擁有了該對(duì)象,你可以將 PropertyValuesHolder 作為參數(shù)獲取一個(gè)Animator,如下:

2.2.9 KeyFrameSet
根據(jù) Animator 傳入的值,為當(dāng)前動(dòng)畫(huà)創(chuàng)建一個(gè)特定類(lèi)型的 KeyFrame 集合。
通常通過(guò) ObjectAnimator.ofFloat(...)進(jìn)行賦值時(shí),這些值其實(shí)是通過(guò)一個(gè) KeyFrameSet 來(lái)維護(hù)的
比如:

調(diào)用者傳入的 values 為 50,100,200,則 numKeyframs = 3,那么創(chuàng)建出相應(yīng)的 Keyframe 為: Keyframe(0,50),Keyframe(1/2,100),Keyframe(1,200), 時(shí)間點(diǎn) 0,1/2,1 都是按比例劃分的

2.3 在 XML 中聲明屬性動(dòng)畫(huà)
通過(guò)在 XML 中定義的動(dòng)畫(huà),可以很方便的在多個(gè) Activities 中重用而且更容易編輯,復(fù)用性強(qiáng)。為了區(qū)分新的屬性動(dòng)畫(huà),從 3.1 開(kāi)始,你應(yīng)res/animator/下存放屬性動(dòng)畫(huà)的資源文件,使用animator文件夾是可選的,但是如果你想在 Eclipse ADT 插件中使用布局編輯工具(ADT 11.0.0+),就必須在res/animator文件夾下存放了,因?yàn)?ADT 只會(huì)查找res/animator文件夾下的屬性動(dòng)畫(huà)資源文件。
屬性動(dòng)畫(huà)支持的 Tag 有
ValueAnimator - <animator>
ObjectAnimator - <objectAnimator>
AnimatorSet - <set>


目錄?res/animator/filename.xm
編譯后的資源為
ValueAnimator,?ObjectAnimator, or?AnimatorSet
XML 文件的根元素必須為<set>,<objectAnimator>, or <valueAnimator>之一。也可以在一個(gè) set 中組織不同的動(dòng)畫(huà),包含其它<set>元素,也就是說(shuō),可以嵌套。

2.3.2 元素介紹
2.3.2.1?
動(dòng)畫(huà)集合節(jié)點(diǎn),有一個(gè)屬性 ordering,表示它的子動(dòng)畫(huà)啟動(dòng)方式是先后有序的還是同時(shí)。
屬性
sequentially:動(dòng)畫(huà)按照先后順序
together (default) :動(dòng)畫(huà)同時(shí)啟動(dòng)
2.3.2.2?
一個(gè)對(duì)象的一個(gè)屬性,相應(yīng)的 Java 類(lèi)為:ObjectAnimator
屬性
android:propertyName:
String 類(lèi)型,必須要設(shè)定的值,代表要執(zhí)行動(dòng)畫(huà)的屬性,通過(guò)名字引用,比如你可以指定了一個(gè) View 的"alpha" 或者 "backgroundColor",這個(gè) objectAnimator 元素沒(méi)有暴露 target 屬性,因此不能夠在 XML 中執(zhí)行一個(gè)動(dòng)畫(huà),必須通過(guò)調(diào)用loadAnimator()?填充你的 XML 動(dòng)畫(huà)資源,并且調(diào)用setTarget()?應(yīng)用到擁有這個(gè)屬性的目標(biāo)對(duì)象上。
android:valueTo
Float、int 或者 color,也是必須值,表明了動(dòng)畫(huà)結(jié)束的點(diǎn),顏色由 6 位十六進(jìn)制的數(shù)字表示。
android:valueFrom
相對(duì)應(yīng) valueTo,動(dòng)畫(huà)的起始點(diǎn),如果沒(méi)有指定,系統(tǒng)會(huì)通過(guò)屬性身上的 get 方法獲取,顏色也是 6 位十六進(jìn)制的數(shù)字表示。
android:duration
動(dòng)畫(huà)的時(shí)長(zhǎng),int 類(lèi)型,以毫秒為單位,默認(rèn)為 300 毫秒。
android:startOffset
動(dòng)畫(huà)延遲的時(shí)間,從調(diào)用 start 方法后開(kāi)始計(jì)算,int 型,毫秒為單位,
android:repeatCount
一個(gè)動(dòng)畫(huà)的重復(fù)次數(shù),int 型,”-1“表示無(wú)限循環(huán),”1“表示動(dòng)畫(huà)在第一次執(zhí)行完成后重復(fù)執(zhí)行一次,也就是兩次,默認(rèn)為 0,不重復(fù)執(zhí)行。
android:repeatMode
重復(fù)模式:int 型,當(dāng)一個(gè)動(dòng)畫(huà)執(zhí)行完的時(shí)候應(yīng)該如何處理。該值必須是正數(shù)或者是 -1,
“reverse”
會(huì)使得按照動(dòng)畫(huà)向相反的方向執(zhí)行,可實(shí)現(xiàn)類(lèi)似鐘擺效果。
“repeat”
會(huì)使得動(dòng)畫(huà)每次都從頭開(kāi)始循環(huán)。
android:valueType
關(guān)鍵參數(shù),如果該 value 是一個(gè)顏色,那么就不需要指定,因?yàn)閯?dòng)畫(huà)框架會(huì)自動(dòng)的處理顏色值。有 intType 和 floatType 兩種:分別說(shuō)明動(dòng)畫(huà)值為 int 和 float 型。
2.3.2.3 <animator>
在一個(gè)特定的時(shí)間里執(zhí)行一個(gè)動(dòng)畫(huà)。相對(duì)應(yīng)的是 ValueAnimator.所有的屬性和一樣 android:valueTo
android:valueFrom
android:duration
android:startOffset
android:repeatCount
android:repeatMode
android:valueType
Value Description
floatType (default)
res/animator/property_animator.xml:

為了執(zhí)行該動(dòng)畫(huà),必須在代碼中將該動(dòng)畫(huà)資源文件填充為一個(gè) AnimationSet 對(duì)象,然后在執(zhí)行動(dòng)畫(huà)前,為目標(biāo)對(duì)象設(shè)置所有的動(dòng)畫(huà)集合。
簡(jiǎn)便的方法就是通過(guò) setTarget 方法為目標(biāo)對(duì)象設(shè)置動(dòng)畫(huà)集合,代碼如下:

三 View anim 與 property anim 的比較
View anim 系統(tǒng)
view animation system 提供的能力只能夠?yàn)?View 添加動(dòng)畫(huà)。因此如果你想為非 View 對(duì)象添加動(dòng)畫(huà),就必須自己去實(shí)現(xiàn), view animation system 在 View 動(dòng)畫(huà)的展現(xiàn)方面也是有約束的,只暴露了 View 的很少方面。比如 View 支持縮放和旋轉(zhuǎn),但不支持背景顏色的動(dòng)畫(huà)。
view animation system 的另一劣勢(shì)是,其改變的是 View 的繪制效果,真正的 View 的屬性保持不變,比如無(wú)論你在對(duì)話(huà)中如何縮放 Button 的大小,Button 的有效點(diǎn)擊區(qū)域還是沒(méi)有應(yīng)用到動(dòng)畫(huà)時(shí)的區(qū)域,其位置與大小都不變。
但是 View animation system 只需花費(fèi)很少時(shí)間創(chuàng)建而且只需很少的代碼。如果 View 動(dòng)畫(huà)完成了你所有的動(dòng)作,或者你存在的代碼已經(jīng)達(dá)到了你想要的效果,就沒(méi)必要使用 property 動(dòng)畫(huà)系統(tǒng)了。
property anim 系統(tǒng)
完全彌補(bǔ)了 View anim System 的缺陷,你可以為一個(gè)對(duì)象的任何屬性添加動(dòng)畫(huà),(View 或者非 View),同時(shí)對(duì)象自己也會(huì)被修改。 并且當(dāng)屬性變化的時(shí)候,property Anim 系統(tǒng)會(huì)自動(dòng)的刷新屏幕。
屬性動(dòng)畫(huà)系統(tǒng)在處理動(dòng)畫(huà)方面也更加強(qiáng)勁。更高級(jí)的,你可以指定動(dòng)畫(huà)的屬性,比如顏色,位置,大小,定義動(dòng)畫(huà)的插值器并且同步多個(gè)動(dòng)畫(huà)。
并且在 Property Animation 中,改變的是對(duì)象的實(shí)際屬性,如 Button 的縮放,Button 的位置與大小屬性值都改變了。而且 Property Animation 不止可以應(yīng)用于 View,還可以應(yīng)用于任何對(duì)象。
平時(shí)使用的簡(jiǎn)單動(dòng)畫(huà)特效,使用 View 動(dòng)畫(huà)就可以滿(mǎn)足,但是如果你想做的更加復(fù)雜,比如背景色的動(dòng)畫(huà),或者不僅是 View,還希望對(duì)其它對(duì)象添加動(dòng)畫(huà)等,那么你就得考慮使用 Property 動(dòng)畫(huà)了。