Android屬性動畫(第一話)
幀動畫,補間動畫
Android動畫能給界面帶來很炫的效果,如果我們要實現(xiàn)這些效果,在android3.0版本前實現(xiàn)動畫主要有2種方式,幀動畫和補間動畫。
幀動畫加載大量圖片,對性能有很大要求效率不高,補間動畫是對view進行包括縮放,移動,旋轉,透明度的繪制。因為補間動畫實現(xiàn)不了動畫操作后的view的點擊等操作,只是簡單在操作后的地方顯示一個,并不會加上view原來的屬性,比如一個button從父容器左上角移動到右下角,他的點擊事件還在左上角。
介紹屬性動畫
為了解決上述問題,新推出了View的屬性動畫,原理是改變view的屬性,所以我們可以操作縮放移動透明度旋轉后的view,原理是在一段時間內不斷設置View.setRotation(),下面我們來介紹一下ValueAnimator。
ValueAnimator
//動畫是200毫秒內view由0過渡到1
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 1f);
valueAnimator.setDuration(200);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//監(jiān)聽輸出動畫移動的值
float value = (float) animation.getAnimatedValue();
}
});
valueAnimator.start();
生成ValueAnimator的方法除了ValueAnimator.ofFloat(float);參數要精確到小數點后幾位,還有ValueAnimator.ofInt(int);參數是整型比如1,100。
ValueAnimator還有其他屬性,比如設置延遲時間ValueAnimator.setStartDelay(200);設置延時200毫秒,還有循環(huán)次數
ValueAnimator.setRepeatCount(5);動畫循環(huán)5次,又或者是動畫播放模式正常ValueAnimator.RESTART還是反向播放的
ValueAnimator.setRepeatMode(ValueAnimator.REVERSE);發(fā)向播放動畫。
ObjectAnimator
ObjectAnimator繼承了ValueAnimator,所以ValueAnimator有的方法ObjectAnimator都有。ObjectAnimator是操作具體的控件比如button,imageview的動畫,舉幾個例子:
圖片從x軸的-500的位置移動到100的位置
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(mImageView,"translationX",-500f,100f);
objectAnimator.setDuration(500);
objectAnimator.start();
透明度由1變成0再變成1的動畫
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(mImageView,"alpha",1f,0f,1f);
objectAnimator.setDuration(500);
objectAnimator.start();
旋轉360度的動畫
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(mImageView,"rotation",0f,360f);
objectAnimator.setDuration(500);
objectAnimator.start();
y軸上縮放3倍的動畫
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(mImageView,"scaleY",1f,3f);
objectAnimator.setDuration(500);
objectAnimator.start();
如果你覺得單單實現(xiàn)一種動畫還不夠炫,如果你想同時實現(xiàn)多個動畫,你要用到動畫組合AnimatorSet
AnimatorSet
把多個ObjectAnimator按順序連接起來,比如把上面的縮放,移動,設置透明度組合起來
ObjectAnimator scaleYAnimator=ObjectAnimator.ofFloat(mImageView,"scaleY",1f,3f);
ObjectAnimator translationXAnimator=ObjectAnimator.ofFloat(mImageView,"translationX",0f,100f);
ObjectAnimator alphaAnimator=ObjectAnimator.ofFloat(mImageView,"alpha",1f,0f,1f);
AnimatorSet animatorSet=new AnimatorSet();
animatorSet.play(scaleYAnimator).with(translationXAnimator).with(alphaAnimator);
animatorSet.setDuration(500);
animatorSet.start();
這里Animator.after將其他動畫加到這個動畫之后,還可以傳入動畫設置兩個動畫的間隔,Animator.with兩個動畫一起播放,Animator.before插入動畫放在這個動畫之前。
動畫監(jiān)聽器
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(mImageView,"scaleY",1f,3f);
objectAnimator.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) {
//動畫循環(huán)時
}
});
objectAnimator.setDuration(500);
objectAnimator.start();
你也可以單獨實現(xiàn)一個監(jiān)聽方法,這里的AnimatorListener改為AnimatorListenerAdapter就可以了
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
設置XML動畫
如果有多個界面的控件要實現(xiàn)相同的動畫效果,我們可以通過xml更加有效率來設置動畫。
在res/animator文件夾下新建animator.xml
(注意,res/anim這個文件夾是放補間動畫的)
根標簽是一個<objectAnimator> 代表一個ObjectAnimator,標簽內有duration動畫時間,propertyName動畫屬性translationX,valueFrom原來的值,valueTo變化后的值,valueType值的類型是floatType還是intType這些屬性.
<set>標簽代表一個AnimatorSet,在set標簽內默認按照從上到下順序加載不同的動畫(就是在set設置android:ordering="sequentially"),如果你想同步進行就設置android:ordering="together"
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<objectAnimator
android:duration="500"
android:propertyName="scaleY"
android:valueFrom="100f"
android:valueTo="1f"
android:valueType="floatType"
/>
<set android:ordering="together">
<objectAnimator
android:duration="500"
android:propertyName="scaleY"
android:valueFrom="1f"
android:valueTo="100f"
android:valueType="floatType"
/>
</set>
</set>
xml代碼寫好了,然后實現(xiàn)可以在類中調用
Animator animator = AnimatorInflater.loadAnimator(mContext, R.animator.animator);
animator.setTarget(mImageView);
animator.start();
最后通過夠用AnimatorInflate.loadAnimator,參數分別是Context和R.animator.animator
總結
上述分別講述了幀動畫,補間動畫,屬性動畫的ValueAnimator,ObejectAnimator 和AnimatorSet,還有屬性動畫的xml寫法。
從性能效率上來看,優(yōu)先考慮使用屬性動畫。