屬性動畫是 Android API level 11(Android 3.0)中添加的動畫框架,功能強大,擴展性強。介紹屬性動畫,就須要說明三個問題:java
屬性是什麼?git
用官方的話說,Property is a field in an object。更進一步解釋,這裏的屬性是指一個對象中具備 setter/getter 方法的變量。github
屬性動畫能夠作什麼?網絡
通常來講,動畫是一種視覺效果,可是屬性動畫的內容要更普遍,除了作一些視覺效果以外,屬性動畫還能夠用相似動畫的方式默默改變一些數據。固然,最主要的仍是實現視覺效果,包括常見的透明度、縮放、平移、旋轉效果,也能夠擴展出其餘的屬性(好比顏色)。框架
與以前的 View Animation 有什麼區別?ide
View Animation 是在 API level 1 開始支持的動畫框架,內容只有基本的透明度、縮放、平移、旋轉,且動畫的對象只能是 View。工具
兩者的區別有如下幾點:動畫
屬性動畫中新添加的類主要是這些: lua
做爲屬性動畫的基類,Animator 提供了動畫最基本的屬性。spa
僅列出一部分(我以爲)經常使用的。
Method Name | Function |
---|---|
start() |
開始播放 |
cancel() |
取消動畫 |
isRunning() |
是否正在播放 |
addListener | 添加監聽回調 |
setTarget | 設置動畫目標Object |
setDuration | 設置播放時長,單位:毫秒 |
setInterpolator | 設置插值器 |
關於插值器的內容本文暫不介紹了。
構造方法
//直接建立
ValueAnimator valueAnimator = new ValueAnimator();
//帶參數建立
ValueAnimator valueAnimator = ValueAnimator.ofFloat(1.0f, 2.0f);
// ValueAnimator valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), Color.RED, Color.GREEN);
// ...還有ofArgb,ofInt,ofPropertyValuesHolder
複製代碼
比起 Animator 增長的一些經常使用方法
Method Name | Function |
---|---|
setStartDelay | 設置動畫啓動延遲,單位:毫秒 |
addUpdateListener | 添加Value更新的監聽回調 |
setRepeatMode | 設置重複播放模式,RESTART或REVERSE |
setRepeatCount | 設置重複播放次數 |
構造方法
//直接建立
ObjectAnimator objectAnimator = new ObjectAnimator();
//帶參數建立
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mView, "alpha", 1.0f, 0.7f);
//...相似的構造方法有不少,就是參數不一樣,這些參數均可以經過setter方法設置。
複製代碼
ObjectAnimatior 增長了屬性動畫最基本的方法——設置屬性。
Method Name | Function |
---|---|
setProperty | 設置動畫目標屬性 |
setPropertyName | 經過name設置動畫目標屬性 |
setIntValues(int... values) |
設置一系列動畫參數,按順序執行 |
setFloatValues(float... values) |
設置一系列動畫參數,按順序執行 |
setObjectValues(Object... values) |
設置一系列動畫參數,按順序執行 |
AnimatorSet 的功能就是把多個各類 Animator 對象整合成一個動畫,有點相似與 ViewGroup。
Method Name | Function |
---|---|
playTogether | 多個動畫一塊兒播放 |
playSequentially | 多個動畫順序播放 |
ValueAnimator 的功能很單一,比較像「時間軸」,就是設置一個值,在一段時間內以某種規則變化。這也是 ObjectAnimator 實現動畫的基礎。
舉個例子,經過 VlaueAnimator 改變 View 的顏色:
private int mColor = Color.RED;
public ValueAnimator valueAnimator;
//...
//...
valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), mColor, Color.rgb(0,0,255));
valueAnimator.setDuration(3000);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mColor = (int) animation.getAnimatedValue();
}
});
複製代碼
在 onAnimationUpdate
方法中把變化後的顏色刷新到 UI 界面就好了。效果是這樣的:
相比之下 ObjectAnimator 纔是屬性動畫中的主角,建立 ObjectAnimator 對象實現動畫須要有幾個要素:
屬性名接受一個 String 類型的參數,就很容易出錯。能夠經過輸入 target 的 object 對象,在代碼提示中找 setter 方法來肯定屬性名。View 的屬性名是比較經常使用的,好比:
alpha
,rotation
,scaleX
,scaleY
,translationX
,translationY
,rotationX
,rotationY
等。
舉個例子,網絡加載中可能會大量用到的一種loading動畫。
ObjectAnimator animator = new ObjectAnimator();
animator.setPropertyName("rotation");
animator.setTarget(ivLoading);
animator.setFloatValues(0,360);
animator.setDuration(900);
animator.setRepeatMode(ObjectAnimator.RESTART);
animator.setRepeatCount(ObjectAnimator.INFINITE);
animator.setInterpolator(new LinearInterpolator());
animator.start();
複製代碼
代碼含義比較清晰,須要注意的是setInterpolator
默認的插值器並非線性的,下面給出兩種效果,左側是 LinearInterpolator ,右側是默認的。
xml 實現動畫是一種比較合理的複用動畫方式,能夠有效避免在 Controller 層寫過多隻屬於 View 層的代碼。
屬性動畫的 xml 文件須要放在res/animator
文件夾下。
語法與 View Animation 差異比較大,大概是這樣子的:
直觀感覺就是比 View Animation 的 xml 實現麻煩不少,實際上因爲 xml 文件的限制兩者功能上差很少,應該是 View Animation 更加經常使用一點。(我的感覺)
ObjectAnimator 的代碼寫起來不怎麼好看,由於老是在 objectAnimator.xxx(),比起單獨在Activity中實現某些交互效果,把簡單而經常使用的動畫效果封裝成工具類會更理想一些。可是交互效果是變幻無窮的,總有一些獨特的動畫沒法複用。
因而在 API level 12 中,出現了針對 View 的屬性動畫 ViewPropertyAnimtor。ViewProperty 中封裝了 View 相關的經常使用動畫參數的設置以及多種回調,並用 ObjectAnimator 實現了動畫效果,對外提供了至關簡單易懂的流式 API,使動畫的代碼也能夠寫的很爽。
使用方法:
- 獲取 ViewPropertyAnimator 對象
ViewPropertyAnimator 沒有 public 的構造方法,只能經過 View 對象的 animate()
方法得到。使用的 View 對象就是動畫的 target。
ViewPropertyAnimator 對象是會重複使用的,屢次調用'animate()'只會建立一個 ViewPropertyAnimator。
- 設置動畫參數
相關的 API 名稱都很明確,就不一一介紹效果了
- 設置回調(可選)
就是setListener
方法。其實全部的動畫均可以設置 Listener ,只是在 ViewPropertyAnimator 中更加劇要,由於從 API 能夠看出每一種動畫只能傳入一個參數,若是須要同一種動畫多段執行,就只能經過監聽動畫結束脩改參數值再開始動畫。
setListener
方法接收一個 Animator.AnimatorListener 接口的實例,能夠直接建立 Animator.AnimatorListener 實例實現全部方法,也能夠建立 AnimatorListenerAdapter 只重寫須要的方法。
ViewPropertyAnimator 的複用一樣會影響 Listener,若是是同一個 View 的多個動畫且不相關,須要在不須要 Listener 的動畫中調用setListener(null)
。
這裏也應該舉個例子,不過沒什麼好的想法,姑且再寫一遍 loading 動畫,就當對比一下兩種 API 格式吧。(kotlin代碼,對比一下設置動畫的 API 就行了)
ivLoadingRight.setOnClickListener {
ivLoadingRight.animate()
.rotationBy(360f)
.setDuration(800)
.setInterpolator(LinearInterpolator())
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
ivLoadingRight.animate()
.rotationBy(360f)
.setDuration(800)
.setInterpolator(LinearInterpolator())
.start()
}
}).start()
複製代碼
由於我並無作過太多的動畫效果,剛開始寫的時候只想總結一下各類方法的用法和效果,然而那樣就會不能避免的翻譯官方文檔,且內容雜亂,不易整理 demo。因而先寫了一些簡單的動畫效果,依據實際代碼反向整理了這篇文章。
文中 gif 圖對應代碼都在示例工程(AnimatorSample)中,地址:https://github.com/xhd-Git/Samples