該文章是一個系列文章,是本人在Android開發的漫漫長途上的一點感想和記錄,我會盡可能按照先易後難的順序進行編寫該系列。該系列引用了《Android開發藝術探索》以及《深刻理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相關知識,另外也借鑑了其餘的優質博客,在此向各位大神表示感謝,膜拜!!!android
上一篇文章呢,咱們說了關於View動畫的那些事,這裏也在總結一下,使用View動畫時須要注意如下4點:(更多詳情請參看個人上一篇博客。)git
那麼本章呢是來介紹Android動畫的另一個大類屬性動畫github
屬性動畫是API11新加入的特性,和View動畫不一樣,它能夠對任何對象作動畫,甚至還能夠沒有對象,動畫默認時間間隔300ms,默認幀率10ms/幀。其能夠達到的效果是:在一個時間間隔內完成對對象從一個屬性值到另外一個屬性值得改變。經常使用屬性動畫類ValueAnimator、ObjectAnimator和AnimationSet,其中ObjectAnimator繼承於ValueAnimator.
注:gihub上JakeWharton大神對API11以前作了屬性動畫的兼容,它的原理其實也很簡單,主要就是判斷當前sdk版本,若是大於API11,那麼就調用官方的API,不然本身實現動畫效果。另外,在API使用方面,它與官方的屬性動畫基本一致。另外,在API使用方面,它與官方的屬性動畫基本一致。好比ObjectAnimator、ValueAnimator等等。 感興趣的同窗能夠訪問該項目的github網址NineOldAndroidsapp
Java代碼實現
例如改變一個對象(obj)的translationY屬性,能夠寫爲ide
ValueAnimator.ofFloat(obj,"translationY",100);
XML實現(屬性動畫的XML描述語法的固定格式)動畫
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering=["sequentially"|"together"]> <objectAnimator android:propertyName="string" android:duration="int" android:valueFrom="float|int|color" android:valueTo="float|int|color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["restart"|"reverse"] android:valueType=["colorType"|"intType"]> </objectAnimator> <animator android:duration="int" android:valueFrom="float|int|color" android:valueTo="float|int|color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["restart"|"reverse"] android:valueType=["colorType"|"intType"]> </animator> ... </set>
不少屬性都是見名知義的,下面呢簡單介紹一下各屬性名稱的含義。
屬性動畫的核心類有3個類,AnimatorSet,ObjectAnimator以及ValueAnimatorthis
android:duration:表示動畫的時長
android:valueFrom:表示屬性的起始值
android:valueTo:表示屬性的結束值
android:startOffset:表示動畫的延遲時間,動畫開始後,須要延遲多少毫秒後纔會真正播放該動畫
android:repeatCount:表示動畫的重複次數,默認值是0,爲-1時,表示無限循環。
android:repeatMode:表示動畫的重複播放模式,restart表示動畫每次都是從新開始播放,reverse表示動畫第1 次播放完畢後,第2次會逆向播放,第3次又從頭開始播放,以此類推lua
android:propertyName:表示屬性動畫做用對象的屬性名稱
android:valueType:表示android:propertyName的值的類型,分爲intType,和floatType,分別表明整型數值和浮點型數值,若android:propertyName指定的屬性表示的是顏色,那麼無需指定android:valueType,系統會自動適配
其餘屬性的含義與上面的<animatior>一致。rest
咱們先來看一個需求:要求對一個Button作動畫,要求讓其寬度從原始寬度增長到500px。這也太簡單了,code
Button mButton = (Button) findViewById(R.id.button); ObjectAnimator.ofInt(mButton,"width",500).setDuration(1000).start();
程序運行,可是卻沒有效果,這是爲何呢,仔細想一想沒效果也是應該的,由於你隨便傳遞了一個屬性名稱過去,輕則動畫沒有效果,重則直接Crash。那麼這個號稱能夠對任意屬性作動畫的屬性動畫使用的時候有哪些須要注意的地方呢
以上的條件缺一不可
這時又有一個問題若是想要對一個對象的屬性作動畫,可是屬性又沒有對應的get和set方法怎麼辦呢??
歸納來說有以下3種解決辦法:
下面仍以上面Button的寬度動畫做爲需求給出方法2,3的解決代碼
方法2:
mButton = (Button) findViewById(R.id.button); ObjectAnimator.ofInt(new ViewWrapper(mButton),"width",500).setDuration(1000).start(); private class ViewWrapper{ private View mTarget; public ViewWrapper(View mTarget) { this.mTarget = mTarget; } public int getWidth() { return mTarget.getLayoutParams().width; } public void setWidth(int width) { mTarget.getLayoutParams().width = width; mTarget.requestLayout(); } }
方法3:
使用方法3以前,咱們先來看屬性動畫的監聽器AnimatorUpdateListener和AnimatorListener
public static interface AnimatorListener { void onAnimationStart(Animator animation); void onAnimationEnd(Animator animation); void onAnimationCancel(Animator animation); void onAnimationRepeat(Animator animation); }
如上代碼所示AnimatorListener監聽了動畫的開始、結束、取消和重複播放,同時系統提供了AnimatorListenerAdapter適配器方便咱們使用,咱們能夠繼承這個類並有選擇的實現方法。
public static interface AnimatorUpdateListener { /** * <p>Notifies the occurrence of another frame of the animation.</p> * * @param animation The animation which was repeated. */ void onAnimationUpdate(ValueAnimator animation); }
如上圖所示,AnimatorUpdateListener 監聽了動畫的整個過程,動畫每播放一幀,onAnimationUpdate就被調用一次,
下面就來看一下如何使用上面的屬性動畫的監聽器來實現屬性動畫
mButton = (Button) findViewById(R.id.button); performAnimate(mButton, mButton.getWidth(), 500); private void performAnimate(final View target, final int start, final int end) { ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { // 持有一個IntEvaluator對象,方便下面估值的時候使用 private IntEvaluator mEvaluator = new IntEvaluator(); @Override public void onAnimationUpdate(ValueAnimator animator) { // 得到當前動畫的進度值,整型,1-100之間 int currentValue = (Integer) animator.getAnimatedValue(); Log.d(TAG, "current value: " + currentValue); // 得到當前進度佔整個動畫過程的比例,浮點型,0-1之間 float fraction = animator.getAnimatedFraction(); // 直接調用整型估值器經過比例計算出寬度,而後再設給Button target.getLayoutParams().width = mEvaluator.evaluate(fraction, start, end); target.requestLayout(); } }); valueAnimator.setDuration(5000).start(); }
本章呢接着上一篇說了Android動畫的另一個大類屬性動畫,至此Android動畫相關的文章完結,因筆者水平有限,因此有不當之處還請指出
此致,敬禮