Android動畫之屬性動畫基礎用法
在上一篇Android動畫基礎之補間動畫與逐幀動畫 ,我們複習了Android的基礎動畫Tweened Animation、Frame Animation,同時指出他們的缺陷,改變是View的顯示效果而不是View本身的屬性,還有我們不多不少會看多人家的APP有一些很酷炫的動畫效果,但是我們Android本身的基礎動畫是用硬編碼方式完成的,功能很有限,擴充套件性很差,無法滿足的現今的產品需求。因為我們今次的主角要出現了,Property Animation屬性動畫。
屬性動畫(Property Animation) 屬性動畫是在Android3.0中引進的,它更改的是物件的實際屬性,在基礎動畫中改變的是View的繪製效果,真正的View的屬性是沒有改變的,而屬性動畫,改變的是物件的實際屬性,能編寫各種滿足我們需求的動畫。
Property Animation相關類:
ValueAnimator:包括Property Animation動畫的所有核心功能,如動畫時間、開始、結束屬性值。
ObjectAnimator:繼承於ValueAnimator,要指定一個物件及該物件的一個屬性,當屬性值計算完成時自動設定為改該物件的相對屬性。實際應用中一般會用ObjectAnimator來改變某一物件的某一屬性。
AnimatorSet:提供了一個把多個動畫組合成一個組合的機制。
AnimatorInflater:用於載入屬性動畫的xml檔案
TypeEvalutors:型別估值,主要用於設定動畫操作屬性的值
Android提供了以下幾個evalutor:
IntEvaluator:屬性的值型別為int;
FloatEvaluator:屬性的值型別為float;
ArgbEvaluator:屬性的值型別為十六進位制顏色值;
- TimeInterplator:時間差值,定義了動畫屬性值變化的方式,在Property Animation中是TimeInterplator,在View Animation中是Interplator,這兩個是一樣的,在3.0之前只有Interplator,3.0之後實現程式碼轉移至了 TimeInterplator。Interplator繼承自TimeInterplator,內部沒有任何其他程式碼。
ValueAnimator
- 呼叫ValueAnimator提供的靜態方法例項化ValueAnimator物件,如ofArgb(int… values)、ofFloat(float… values)等,並設定目標屬性的屬性名、初始值、結束值等;
- 呼叫ValueAnimator.addUpdateListener(AnimatorUpdateListener listener)為ValueAnimator物件設定屬性變化的監聽器;
- 建立自定義的Interpolator,呼叫setInterpolator(TimeInterpolator value)為ValueAniamtor設定自定義的Interpolator;
- 建立自定義的TypeEvaluator,呼叫setEvaluator(TypeEvaluator value)為ValueAnimator設定自定義的TypeEvaluator;
- 在AnimatorUpdateListener中的實現方法為目標物件的屬性設定計算好的屬性值;
- 設定動畫的持續時間、是否重複及重複次數等屬性;
- 對ValueAnimator設定目標物件並開始執行動畫。
下面我們簡單地使用一下ValueAnimator:
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 100);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.i("onAnimationUpdate", "onAnimationUpdate: " + animation.getAnimatedValue());
}
});
valueAnimator.setDuration(200);
valueAnimator.start();
上面程式碼我們是用ofInt()方法,帶的引數是0,100,然後通過用AnimatorUpdateListener設定動畫監聽,如下圖看到動畫的值在200毫秒內從0到100打印出來。
ObjectAnimator
我們接著學習一下ObjectAnimator這動畫實現類的用法,首先ObjectAnimator繼承ValueAnimator,那就說ObjectAnimator可以重寫ValueAnimator父類提供的方法。在實際開發中,我們更多地使用ObjectAnimator來實現我們需要的動畫效果。在之前我們說過ViewAnimation的缺點,所以Android3.0中為View增加了一些新屬性以及對應的getter、setter方法。那我們來看一下這些新增的動畫屬性:
1.translationX和translationY:這兩個屬性控制著View的螢幕位置座標變化量,以layout容器的左上角為座標原點;
2.rotation、rotationX 和 rotationY:這三個屬性控制著 2D 旋轉角度(rotation屬性)和圍繞某樞軸點的 3D 旋轉角度;
3.scaleX、scaleY:這兩個屬性控制著 View 圍繞某樞軸點的 2D 縮放比例;
4.pivotX 和 pivotY: 這兩個屬性控制著樞軸點的位置,前述的旋轉和縮放都是以此點為中心展開的,預設的樞軸點是 View 物件的中心點;
5.x 和 y:這是指 View 在容器內的最終位置,等於 View 左上角相對於容器的座標加上 translationX 和 translationY 後的值;
alpha:表示 View 的 alpha 透明度。預設值為 1 (不透明),為 0 則表示完全透明(看不見);
然而用法跟ValueAnimator大同小異,我們通過例子來說明:
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);
animator.setDuration(1000);
animator.start();
感覺是沒區別啊,我們ObjectAnimator其實是對繼承了View控制元件的屬性setter、getter方法進行修改值的。ObjectAnimator可以在屬性上進行操作,而ValueAnimator並沒有在屬性上做操作,ObjectAnimator對一些簡單的動畫使用起來比較方便,而ValueAnimator就比較靈活,之後我們會詳細講解。
組合動畫AnimatorSet
組合動畫,PropertyAnimation是用到AnimatorSet這個類,該類提供一個play()的方法,還有提供:
- after(Animator anim) 將現有動畫插入到傳入的動畫之後執行
- after(long delay) 將現有動畫延遲指定毫秒後執行
- before(Animator anim) 將現有動畫插入到傳入的動畫之前執行
- with(Animator anim) 將現有動畫和傳入的動畫同時執行
ObjectAnimator moveIn = ObjectAnimator.ofFloat(image, "translationX", -100f, 0f);
ObjectAnimator rotate = ObjectAnimator.ofFloat(image, "rotation", 0f, 180f);
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(image, "alpha", 1f, 0f, 1f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(rotate).with(fadeInOut).after(moveIn);
animSet.setDuration(2000);
animSet.start();
感覺比較基礎的用法。
XML編寫動畫
用XML來編寫描述我們需要的動畫可能是我們最常用的一種做法,所以PropertyAnimation肯定也提供這種XML的方式來實現功能。在XML我們常用到的三個標籤:
<animator>
對應程式碼中的ValueAnimator<objectAnimator>
對應程式碼中的ObjectAnimator<set>
對應程式碼中的AnimatorSet
標籤是可以巢狀的。
標籤的android:ordering屬性規定了這個set中的動畫的執行順序。該屬性值預設是together (default)。
首先要在res目錄下面新建一個animator資料夾,然後我們的XML程式碼的實現如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<objectAnimator
android:duration="2000"
android:propertyName="translationX"
android:valueFrom="-500"
android:valueTo="0"
android:valueType="floatType" />
<set android:ordering="together">
<objectAnimator
android:duration="3000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType" />
<set android:ordering="sequentially">
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType" />
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />
</set>
</set>
</set>
XML檔案寫好,那麼我們用Java程式碼將對於的動畫載入並啟動。
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.anim_set);
animator.setTarget(image);
animator.start();
Animator監聽器
在動畫的繪製中,肯定少不了我們的動畫監聽事件來處理各種需求和邏輯,Animator類當中提供了一個addListener()方法:
mAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
可以看到,我們需要實現介面中的四個方法,onAnimationStart()方法會在動畫開始的時候呼叫,onAnimationRepeat()方法會在動畫重複執行的時候呼叫,onAnimationEnd()方法會在動畫結束的時候呼叫,onAnimationCancel()方法會在動畫被取消的時候呼叫。
但是有些時候我們可能只想要監聽動畫開始這一個事件,那麼每次都要將四個介面全部實現一遍就顯得非常繁瑣。所以Android提供了一個介面卡類,叫作AnimatorListenerAdapter,使用這個類就可以解決掉實現介面繁瑣的問題了,如下所示:
mAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
}
});
好的,通過本篇文章的學習,我想大家已經對屬性動畫的基本API用法已經有了一定的認識,並把最常用的一些功能都掌握好了。接下來下一篇我們繼續深入學習PropertyAnimation。