組合動畫
實現組合動畫功能主要需要藉助AnimatorSet這個類,這個類提供了一個play()方法,如果我們向這個方法中傳入一個Animator對象(ValueAnimator或ObjectAnimator)將會返回一個AnimatorSet.Builder的實例,AnimatorSet.Builder中包括以下四個方法:- after(Animator anim) 將現有動畫插入到傳入的動畫之後執行
- after(long delay) 將現有動畫延遲指定毫秒後執行
- before(Animator anim) 將現有動畫插入到傳入的動畫之前執行
- with(Animator anim) 將現有動畫和傳入的動畫同時執行
有了這四個方法,我們就可以完成組合動畫的邏輯了,那麼比如說我們想要讓TextView先從屏幕外移動進屏幕,然後開始旋轉360度,旋轉的同時進行淡入淡出操作,就可以這樣寫:
- ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f);
- ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
- ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
- AnimatorSet animSet = new AnimatorSet();
- animSet.play(rotate).with(fadeInOut).after(moveIn);
- animSet.setDuration(5000);
- animSet.start();
Animator監聽器
在很多時候,我們希望可以監聽到動畫的各種事件,比如動畫何時開始,何時結束,然後在開始或者結束的時候去執行一些邏輯處理。這個功能是完全可以實現的,Animator類當中提供了一個addListener()方法,這個方法接收一個AnimatorListener,我們只需要去實現這個AnimatorListener就可以監聽動畫的各種事件了。
ObjectAnimator是繼承自ValueAnimator的,而ValueAnimator又是繼承自Animator的,因此不管是ValueAnimator還是ObjectAnimator都是可以使用addListener()這個方法的。另外AnimatorSet也是繼承自Animator的,因此addListener()這個方法算是個通用的方法。
添加一個監聽器的代碼如下所示:
- anim.addListener(new AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- }
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- }
- @Override
- public void onAnimationCancel(Animator animation) {
- }
- });
可以看到,我們需要實現接口中的四個方法,onAnimationStart()方法會在動畫開始的時候調用,onAnimationRepeat()方法會在動畫重複執行的時候調用,onAnimationEnd()方法會在動畫結束的時候調用,onAnimationCancel()方法會在動畫被取消的時候調用。
但是也許很多時候我們並不想要監聽那麼多個事件,可能我只想要監聽動畫結束這一個事件,那麼每次都要將四個接口全部實現一遍就顯得非常繁瑣。沒關係,爲此Android提供了一個適配器類,叫作AnimatorListenerAdapter,使用這個類就可以解決掉實現接口繁瑣的問題了,如下所示:
這裏我們向addListener()方法中傳入這個適配器對象,由於AnimatorListenerAdapter中已經將每個接口都實現好了,所以這裏不用實現任何一個方法也不會報錯。那麼如果我想監聽動畫結束這個事件,就只需要單獨重寫這一個方法就可以了,如下所示:- anim.addListener(new AnimatorListenerAdapter() {
- });
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- }
- });
使用XML編寫動畫
- <animator> 對應代碼中的ValueAnimator
- <objectAnimator> 對應代碼中的ObjectAnimator
- <set> 對應代碼中的AnimatorSet
那麼比如說我們想要實現一個從0到100平滑過渡的動畫,在XML當中就可以這樣寫:
- <animator xmlns:android="http://schemas.android.com/apk/res/android"
- android:valueFrom="0"
- android:valueTo="100"
- android:valueType="intType"/>
- <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType"
- android:propertyName="alpha"/>
另外,我們也可以使用XML來完成複雜的組合動畫操作,比如將一個視圖先從屏幕外移動進屏幕,然後開始旋轉360度,旋轉的同時進行淡入淡出操作,就可以這樣寫:
- <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" >
- </objectAnimator>
- <set android:ordering="together" >
- <objectAnimator
- android:duration="3000"
- android:propertyName="rotation"
- android:valueFrom="0"
- android:valueTo="360"
- android:valueType="floatType" >
- </objectAnimator>
- <set android:ordering="sequentially" >
- <objectAnimator
- android:duration="1500"
- android:propertyName="alpha"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" >
- </objectAnimator>
- <objectAnimator
- android:duration="1500"
- android:propertyName="alpha"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" >
- </objectAnimator>
- </set>
- </set>
- </set>
最後XML文件是編寫好了,那麼我們如何在代碼中把文件加載進來並將動畫啓動呢?只需調用如下代碼即可:
- Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_file);
- animator.setTarget(view);
- animator.start();