1. 程式人生 > >通過原始碼,手把手帶你學屬性動畫(一)

通過原始碼,手把手帶你學屬性動畫(一)

在 Android 3.0(API level 11) 之後,Google 為 Android添加了屬性動畫(Property Animation),該動畫系統是一個強大的框架,允許開發者對幾乎任何物件進行動畫。

由此可知,屬性動畫致力於為開發者提供更好的動畫解決方案。值得注意的是,屬性動畫已不再針對View設計,而是更偏向於對值進行動畫變換,因此可以操作任何物件的任意屬性

相比於補間動畫,屬性動畫解決了補間動畫移動後點擊時間留在原位的問題,且屬性動畫擴充套件性高、定製性強,不再侷限於縮放、旋轉、透明度、平移等操作。至於二者實際的效果差距不再對比,本系列的文章重點是剖析屬性動畫。

0. 寫本系列教程的初衷

網上有關屬性動畫的教程已經很多了,有很多都講的很好。但我之所以還會去寫這系列文章,只是想從一個不同的角度去分析屬性動畫,讓更多的人認識到原始碼和官方教程的重要性。同時我也會拿捏好度,不會讓讀者過度的沉溺原始碼,畢竟我的文章側重初中級開發人員,這一階段適當但不過分的接觸原始碼,對以後很有幫助。

本系列文章,將帶你由淺入深剖析屬性動畫。我們主要的參考資料是原始碼、官方API文件,期間會不時通過原始碼簡單的分析動畫的實現原理,以瞭解動畫的工作機制,知其然知其所以然,這樣才能更好的掌握屬性動畫。

注:參考的原始碼API等級為23,望知曉。同時建議讀者在學習時,能夠對照原始碼去看,這樣能夠加深理解。

學完本系列文章,你可以自如應對開發中大多數動畫效果。只是在一些複雜、定製性高的情況下,要求我們能夠融會貫通、舉一反三,但是所涉及的內容在本文都會提到,只是講解的篇幅會根據使用頻率的高低有所不同。

廣告:對屬性動畫感興趣的,歡迎關注我的公眾號,以及時獲取最新內容。

1. API 一覽

下面開始正式學習,讓我們先先了解一下與屬性動畫相關的類,以對此屬性動畫系統一個整體的認識,這樣有利於學習後面的知識。

屬性動畫主要依靠抽象類 Animator 的支援,Animator 類位於 android.animation 包下,原始碼中對 Animator 類的註釋如下:

This is the superclass for classes which provide basic support for animations which can be started, ended, and have AnimatorListeners added to them.
該類是對動畫提供基礎支援的類的父類,這些動畫可以被開始、結束,並且可以被新增動畫監聽。

那麼,與屬性動畫相關的、繼承自 Animator 的類有哪些呢?先看一下 Google API 文件對 Animator 類結構的介紹:

為了方便看,我截了一張圖:

Animator的API文件

可以看出,Animator的直接子類有 AnimatorSet 和 ValueAnimator,間接子類有 ObjectAnimator 和 TimeAnimator。為了更直觀的表示繼承關係,我又畫了一個超級簡單的UML圖:

簡單的UML圖

這樣就比較直觀了,接下來,我們就來挨個簡單介紹一下各個類的作用。

2. API 詳解

以下對各個類的介紹,大部分翻譯自官方文件,這樣才能保證準確性。同時,因水平有限,若有錯誤之處還望見諒。標記為“略”的表示不是後面重點介紹的物件。

2.1 Animator(略)

該類是對動畫提供基礎支援的類的父類,這些動畫可以被開始、結束,並且可以被新增動畫監聽。我們平時很少與這個類直接打交道,更多的是用到其子類(ValueAnimator、ObjectAnimator等),以及該類的內部靜態介面。

public static interface AnimatorListener{
    //...
}

該介面是一個動畫監聽器,負責接收動畫過程中的通知,這些通知標識了與動畫相關的事件。這些事件通過介面的回撥方法公開出來,我簡單翻譯整理了一下,如下所示:

public static interface AnimatorListener {
    /**
     * 通知動畫開始
     */
    void onAnimationStart(Animator animation);
    /**
     * 通知動畫結束
     * 當動畫的重複次數為INFINITE(無數次)時,該回調方法將不會被呼叫
     */
    void onAnimationEnd(Animator animation);
    /**
     * 通知當動畫取消
     * 同上,當動畫的重複次數為INFINITE(無數次)時,該回調方法將不會被呼叫
     */
    void onAnimationCancel(Animator animation);
    /**
     * 通知動畫重複
     */
    void onAnimationRepeat(Animator animation);
}

有關動畫監聽的使用,將在後續文章中更新。

2.2 ValueAnimator

class ValueAnimator extends Animator

ValueAnimator 繼承自 Animator,其可以幫助我們對值進行動畫操作。

原始碼中有關該類的註釋翻譯過來就是:

本類為執行動畫提供了一個簡單的計時引擎(timing engine),用來計算動畫完成值(animated values)並設定到目標物件上。

有關該類的註釋並沒有提及 View ,因為其僅針對Value(值)進行動畫變換。儘管如此,它卻是屬性動畫的核心類,後面要介紹的 ObjectAnimator 就是在 ValueAnimator 基礎上進行的二次封裝。

2.3 ObjectAnimator

class ObjectAnimator extends ValueAnimator

ObjectAnimator 繼承自 ValueAnimator,支援對目標物件的屬性進行動畫(animating properties on target objects),但正如上面所說,其實現動畫的核心功能是由 ValueAnimator 支援的。

使用時,通過引數定義需要進行動畫操作的目標物件,以及動畫所針對的屬性名稱。對於屬性名稱,我們要確保物件內部存在相應的 gettersetter 方法,這樣動畫才可以在必要時呼叫以對屬性進行動畫。

2.4 TimeAnimator(略)

class TimeAnimator extends ValueAnimator

TimeAnimator 與 ObjectAnimator一樣,都繼承自 Animator。該類提供了一個簡單的回撥機制,去監聽當前動畫與系統中其他動畫是否同步。該類在實際開發中很少會用,後面也不會再講解,感興趣的可以自己看一下。

2.5 AnimatorSet

class AnimatorSet extends Animator

AnimatorSet 主要用來支援組合動畫,其可以幫助我們在特定的順序下播放一組 Animator 動畫(plays a set of Animator objects in the specified order)。動畫可以被設定為同時播放、非同步播放或者在特定的延時之後播放。

AnimatorSet 操作的物件為 Animator,而 ValueAnimator 和 ObjectAnimator 都是 Animator 的子類,所以都可以藉助 AnimatorSet 實現組合動畫。

我們可以藉助該類定製出許多炫酷的動畫效果,要問有多炫酷,我只能說侷限於你的想象力!

3. 總結

本文就到這兒了,主要就是系統的看了一下與屬性動畫相關的一些類。如果你接觸過屬性動畫,你可能會覺得太簡單了,但是對於一些初學者,簡單的講一些原理性的東西,對於後面的理解十分有幫助。

下面回顧一下本文的內容:

  1. 本系列文章的主要目標,以及我們最終能達到什麼樣的一個水平。
  2. 從Animator出發,瞭解了與熟悉動畫相關的幾個類,並附上了UML圖,你應該對圖中的層級結構瞭然於心;
  3. 著重介紹了一下每個類的作用,以及動畫監聽器AnimatorListener。

通過本文,我們認識了與屬性動畫相關的幾個類,但我們關注的重點只有 ValueAnimator、ObjectAnimator 和 AnimatorSet。當然還有一些輔助屬性動畫的類沒有提及,在後續實戰中會提及,並延伸一些屬性動畫的高階用法,比如插值器、估值器等,以及如何讓自定義它們實現系統沒有提供的效果。

4. 下篇預告

講解 ValueAnimator 和 ObjectAnimator的使用,以及使用動畫監聽器AnimatorListener監聽動畫的過程,具體內容會根據篇幅決定,過完節回來及時更新,敬請期待。

掃描下方二維碼,關注我的公眾號,及時獲取最新文章推送!