整理自:
http://blog.csdn.net/guolin_blog/article/details/43536355
三類(lèi)動(dòng)畫(huà):
補(bǔ)間動(dòng)畫(huà)
屬性動(dòng)畫(huà)
幀動(dòng)畫(huà)(一張一張圖片輪播醒第,有可能會(huì)OOM靶壮,而且很簡(jiǎn)單宴卖,這里不講了)
1、屬性動(dòng)畫(huà)(property animation)
為啥用屬性動(dòng)畫(huà)不用補(bǔ)間動(dòng)畫(huà):
- 你希望View有一個(gè)顏色的切換動(dòng)畫(huà)
- 你希望可以使用3D旋轉(zhuǎn)動(dòng)畫(huà)
- 你希望當(dāng)動(dòng)畫(huà)停止時(shí)纽疟,View的位置就是當(dāng)前的位置
- 對(duì)一個(gè)非View的對(duì)象進(jìn)行動(dòng)畫(huà)操作:比如說(shuō)我們有一個(gè)自定義的View相恃,在這個(gè)View當(dāng)中有一個(gè)Point對(duì)象用于管理坐標(biāo)畦木,然后在onDraw()方法當(dāng)中就是根據(jù)這個(gè)Point對(duì)象的坐標(biāo)值來(lái)進(jìn)行繪制的。也就是說(shuō)申窘,如果我們可以對(duì)Point對(duì)象進(jìn)行動(dòng)畫(huà)操作弯蚜,那么整個(gè)自定義View的動(dòng)畫(huà)效果就有了。
1-1剃法、ValueAnimator
設(shè)置數(shù)值上的平滑增加會(huì)減小
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(300);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentValue = (float) animation.getAnimatedValue();
Log.d("TAG", "cuurent value is " + currentValue);
}
});
anim.start();
用addUpdateListener()方法來(lái)添加一個(gè)動(dòng)畫(huà)的監(jiān)聽(tīng)器
運(yùn)行結(jié)果:
將一個(gè)值在5秒內(nèi)從0過(guò)渡到5碎捺,再過(guò)渡到3,再過(guò)渡到10的代碼:
ValueAnimator anim = ValueAnimator.ofFloat(0f, 5f, 3f, 10f);
anim.setDuration(5000);
anim.start();
其他簡(jiǎn)單的設(shè)置:
- 調(diào)用setStartDelay()方法來(lái)設(shè)置動(dòng)畫(huà)延遲播放的時(shí)間
- 調(diào)用setRepeatCount()和setRepeatMode()方法來(lái)設(shè)置動(dòng)畫(huà)循環(huán)播放的次數(shù)以及循環(huán)播放的模式贷洲,循環(huán)模式包括RESTART和REVERSE兩種收厨,分別表示重新播放和倒序播放的意思。
1-2优构、ObjectAnimator
1-2-1帽氓、動(dòng)畫(huà)舉例
ObjectAnimator可以直接對(duì)任意對(duì)象的任意屬性進(jìn)行動(dòng)畫(huà)操作,比如說(shuō)View的alpha屬性俩块。
因?yàn)镺bjectAnimator其實(shí)是繼承自ValueAnimator的黎休,說(shuō)明ValueAnimator中可以使用的方法在ObjectAnimator中也是可以正常使用的,它們的用法也非常類(lèi)似玉凯。
- 透明度
Eg:將一個(gè)TextView在5秒中內(nèi)從常規(guī)變換成全透明势腮,再?gòu)娜该髯儞Q成常規(guī)
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
animator.setDuration(5000);
animator.start();
- 旋轉(zhuǎn)
將TextView進(jìn)行一次360度的旋轉(zhuǎn)
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
animator.setDuration(5000);
animator.start();
- 移動(dòng)
將TextView先向左移出屏幕,然后再移動(dòng)回來(lái)
float curTranslationX = textview.getTranslationX(); //getTranslationX()方法來(lái)獲取到當(dāng)前TextView的translationX的位置
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "translationX", curTranslationX, -500f, curTranslationX);
animator.setDuration(5000);
animator.start();
- 縮放
將TextView在垂直方向上放大3倍再還原
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f);
animator.setDuration(5000);
animator.start();
這里注意如果要對(duì)一個(gè)View進(jìn)行縮放漫仆,這樣做是沒(méi)用的(好像不能直接對(duì)"scale"進(jìn)行操作)捎拯,要分別對(duì)"scaleY"和"scaleX"進(jìn)行操作:
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scale", 1f, 3f, 1f);
效果:
ofFloat()
的第二個(gè)參數(shù)除了上述這些還有哪些呢?
其實(shí)ObjectAnimator內(nèi)部的工作機(jī)制并不是直接對(duì)我們傳入的屬性名進(jìn)行操作的盲厌,而是會(huì)去尋找這個(gè)屬性名對(duì)應(yīng)的get和set方法署照,因此alpha屬性所對(duì)應(yīng)的get和set方法應(yīng)該就是:
public void setAlpha(float value);
public float getAlpha();
textview對(duì)象的確有這兩個(gè)方法祸泪,并且這兩個(gè)方法是由View對(duì)象提供的,也就是說(shuō)不僅TextView可以使用這個(gè)屬性來(lái)進(jìn)行淡入淡出動(dòng)畫(huà)操作建芙,任何繼承自View的對(duì)象都可以的没隘。
1-2-2、組合動(dòng)畫(huà)
注意這個(gè)組合動(dòng)畫(huà)的做法也適用于ValueAnimator禁荸!
借助AnimatorSet這個(gè)類(lèi)右蒲,這個(gè)類(lèi)提供了一個(gè)play()方法,如果我們向這個(gè)方法中傳入一個(gè)Animator對(duì)象(ValueAnimator或ObjectAnimator)將會(huì)返回一個(gè)AnimatorSet.Builder的實(shí)例赶熟,AnimatorSet.Builder中包括以下四個(gè)方法:
- after(Animator anim) 將現(xiàn)有動(dòng)畫(huà)插入到傳入的動(dòng)畫(huà)之后執(zhí)行
- after(long delay) 將現(xiàn)有動(dòng)畫(huà)延遲指定毫秒后執(zhí)行
- before(Animator anim) 將現(xiàn)有動(dòng)畫(huà)插入到傳入的動(dòng)畫(huà)之前執(zhí)行
- with(Animator anim) 將現(xiàn)有動(dòng)畫(huà)和傳入的動(dòng)畫(huà)同時(shí)執(zhí)行
Eg:讓TextView先從屏幕外移動(dòng)進(jìn)屏幕瑰妄,然后開(kāi)始旋轉(zhuǎn)360度,旋轉(zhuǎn)的同時(shí)進(jìn)行淡入淡出操作
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();
1-2-3映砖、動(dòng)畫(huà)監(jiān)聽(tīng)
注意這個(gè)動(dòng)畫(huà)監(jiān)聽(tīng)的做法也適用于ValueAnimator间坐!
我們希望可以監(jiān)聽(tīng)到動(dòng)畫(huà)的各種事件,比如動(dòng)畫(huà)何時(shí)開(kāi)始邑退,何時(shí)結(jié)束竹宋,然后在開(kāi)始或者結(jié)束的時(shí)候去執(zhí)行一些邏輯處理。
Animator類(lèi)當(dāng)中提供了一個(gè)addListener()方法瓜饥,這個(gè)方法接收一個(gè)AnimatorListener逝撬,我們只需要去實(shí)現(xiàn)這個(gè)AnimatorListener就可以監(jiān)聽(tīng)動(dòng)畫(huà)的各種事件了。
示例代碼:
anim.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
//在動(dòng)畫(huà)開(kāi)始的時(shí)候調(diào)用
}
@Override
public void onAnimationRepeat(Animator animation) {
//在動(dòng)畫(huà)重復(fù)執(zhí)行的時(shí)候調(diào)用
}
@Override
public void onAnimationEnd(Animator animation) {
//動(dòng)畫(huà)結(jié)束的時(shí)候調(diào)用
}
@Override
public void onAnimationCancel(Animator animation) {
//在動(dòng)畫(huà)被取消的時(shí)候調(diào)用
}
});
也可以使用適配器類(lèi)AnimatorListenerAdapter
來(lái)實(shí)現(xiàn)這四個(gè)方法中的任意一個(gè)方法乓土,免得每次都要將四個(gè)接口全部實(shí)現(xiàn)一遍(假設(shè)只想要在動(dòng)畫(huà)結(jié)束之后設(shè)定一些邏輯):
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
}
});
因?yàn)?/p>
1-2-4宪潮、使用XML編寫(xiě)動(dòng)畫(huà)
通過(guò)XML來(lái)編寫(xiě)動(dòng)畫(huà)可能會(huì)比通過(guò)代碼來(lái)編寫(xiě)動(dòng)畫(huà)要慢一些,但是在重用方面將會(huì)變得非常輕松趣苏,比如某個(gè)將通用的動(dòng)畫(huà)編寫(xiě)到XML里面狡相,我們就可以在各個(gè)界面當(dāng)中輕松去重用它。
如果想要使用XML來(lái)編寫(xiě)動(dòng)畫(huà)食磕,首先要在res目錄下面新建一個(gè)animator文件夾尽棕,所有屬性動(dòng)畫(huà)的XML文件都應(yīng)該存放在這個(gè)文件夾當(dāng)中。然后在XML文件中我們一共可以使用如下三種標(biāo)簽:
- <animator> 對(duì)應(yīng)代碼中的ValueAnimator
- <objectAnimator> 對(duì)應(yīng)代碼中的ObjectAnimator
- <set> 對(duì)應(yīng)代碼中的AnimatorSet
- 從0到100平滑過(guò)渡的動(dòng)畫(huà):
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="100"
android:valueType="intType"/>
- 將一個(gè)視圖的alpha屬性從1變成0
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType"
android:propertyName="alpha"/>
- 復(fù)雜的組合動(dòng)畫(huà)操作彬伦,比如將一個(gè)視圖先從屏幕外移動(dòng)進(jìn)屏幕滔悉,然后開(kāi)始旋轉(zhuǎn)360度,旋轉(zhuǎn)的同時(shí)進(jìn)行淡入淡出操作
<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動(dòng)畫(huà)加載進(jìn)來(lái):
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_file);
animator.setTarget(view); //setTarget()方法將這個(gè)動(dòng)畫(huà)設(shè)置到某一個(gè)對(duì)象上面
animator.start();
2单绑、補(bǔ)間動(dòng)畫(huà)
概述:對(duì)View進(jìn)行移動(dòng)回官、縮放、旋轉(zhuǎn)和淡入淡出搂橙,并且我們還可以借助AnimationSet來(lái)將這些動(dòng)畫(huà)效果組合起來(lái)使用歉提,除此之外還可以通過(guò)配置Interpolator來(lái)控制動(dòng)畫(huà)的播放速度