Android動(dòng)畫詳解
Android動(dòng)畫主要分為兩類,傳統(tǒng)動(dòng)畫和Android3.0之后出現(xiàn)的屬性動(dòng)畫
傳統(tǒng)動(dòng)畫又包括幀動(dòng)畫和補(bǔ)間動(dòng)畫
補(bǔ)間動(dòng)畫
補(bǔ)間動(dòng)畫又可以分為四種形式,分別是 alpha(淡入淡出)凉馆,translate(位移)音半,scale(縮放大小)跃须,rotate(旋轉(zhuǎn))。
一般采用xml實(shí)現(xiàn)
XML實(shí)現(xiàn)
alpha_anim.xml動(dòng)畫實(shí)現(xiàn)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--透明度變換 -->
<alpha
android:duration="7000"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
scale_anim.xml動(dòng)畫實(shí)現(xiàn)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<!--尺寸收縮-->
<scale
android:duration="7000"
android:fromXScale="0.5"
android:fromYScale="0.5"
android:interpolator="@android:anim/decelerate_interpolator"
android:pivotX="0%"
android:pivotY="0%"
android:toXScale="3.0"
android:toYScale="3.0" />
</set>
rotate_anim.xml動(dòng)畫實(shí)現(xiàn)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<rotate
android:duration="3000"
android:fromDegrees="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="0%"
android:pivotY="0%"
android:toDegrees="+180" />
</set>
translate_anim.xml動(dòng)畫實(shí)現(xiàn)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<!--位置轉(zhuǎn)移動(dòng)畫-->
<translate
android:duration="5000"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="300"
android:toYDelta="200" />
</set>
在代碼中可以通過
Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.rotate_anim);
ivBack.startAnimation(animation);
這樣的方式使用xml中的各種動(dòng)畫
純代碼實(shí)現(xiàn)
1.透明度動(dòng)畫
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
alphaAnimation.setDuration(3000);
alphaAnimation.setFillAfter(true);
ivBack.startAnimation(alphaAnimation);
2.scale尺寸變換
ScaleAnimation scaleAnimation=new ScaleAnimation(0.0f,3.0f,0.0f,3.0f,150,500);
scaleAnimation.setDuration(4000);
scaleAnimation.setFillAfter(true);
ivBack.startAnimation(scaleAnimation);
3.translate位置變換
//xDelta 使用的是像素值
TranslateAnimation translateAnimation = new TranslateAnimation(0, 700, 0, 700);
translateAnimation.setDuration(4000);
ivBack.startAnimation(translateAnimation);
4.rotate角度變換
RotateAnimation rotateAnimation = new RotateAnimation(0, 180, 0, 0);
rotateAnimation.setDuration(5000);
rotateAnimation.setFillAfter(true);
ivBack.setAnimation(rotateAnimation);
我們給上述的圖像本身做了點(diǎn)擊事件
ivBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "點(diǎn)擊事件", Toast.LENGTH_LONG).show();
}
});
可以看到,角度變換或者尺寸位置變換都不會(huì)改變view本身的位置,點(diǎn)擊事件都對view的初始位置有效.
屬性動(dòng)畫
所有補(bǔ)間動(dòng)畫的內(nèi)容,都可以通過屬性動(dòng)畫實(shí)現(xiàn)。
屬性動(dòng)畫中比較重要的兩個(gè)類
ValueAnimator
屬性動(dòng)畫的運(yùn)行機(jī)制是通過不斷地對值進(jìn)行操作來實(shí)現(xiàn)的池摧,而初始值和結(jié)束值之間的動(dòng)畫過渡就是由ValueAnimator這個(gè)類來負(fù)責(zé)計(jì)算的。它的內(nèi)部使用一種時(shí)間循環(huán)的機(jī)制來計(jì)算值與值之間的動(dòng)畫過渡激况,我們只需要將初始值和結(jié)束值提供給ValueAnimator险绘,并且告訴它動(dòng)畫所需運(yùn)行的時(shí)長,那么ValueAnimator就會(huì)自動(dòng)幫我們完成從初始值平滑地過渡到結(jié)束值這樣的效果誉碴。
如果需要在1秒內(nèi)對0到1的數(shù)值進(jìn)行變換
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(1000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.i("進(jìn)度值", "進(jìn)度值" + animation.getAnimatedValue());
}
});
valueAnimator.start();
可以看到動(dòng)畫執(zhí)行過程中回調(diào)了很多參數(shù)
05-15 16:29:11.068 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.0
05-15 16:29:11.085 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.0
05-15 16:29:11.113 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.0026845932
05-15 16:29:11.132 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.0059125423
05-15 16:29:11.139 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.010709554
05-15 16:29:11.156 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.01690182
05-15 16:29:11.172 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.023988664
05-15 16:29:11.189 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.032835484
05-15 16:29:11.205 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.04237941
05-15 16:29:11.222 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.05378583
05-15 16:29:11.239 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.06646466
05-15 16:29:11.255 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.079527736
05-15 16:29:11.272 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.09457022
05-15 16:29:11.288 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.10978484
05-15 16:29:11.305 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.12702942
05-15 16:29:11.322 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.14533758
05-15 16:29:11.338 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.16349372
05-15 16:29:11.355 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.18371499
05-15 16:29:11.372 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.20357156
05-15 16:29:11.388 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.22548866
05-15 16:29:11.405 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.24818844
05-15 16:29:11.421 12018-12018/? I/進(jìn)度值: 進(jìn)度值0.27021015
ObjectAnimator
ObjectAnimator是ValueAnimator的子類宦棺,它提供了對view操作的多種基礎(chǔ)方法,如rotate,scale,translate,alpha。
XML實(shí)現(xiàn)
屬性動(dòng)畫的屬性值一般會(huì)牽扯到對象具體的屬性,更多是通過代碼動(dòng)態(tài)獲取,所以xml文件的實(shí)現(xiàn)會(huì)有點(diǎn)不方便黔帕。
android:ordering="together" 表明了當(dāng)前set集合的動(dòng)畫播放順序
together則表示同時(shí)并行加載
sequentially則表示順序執(zhí)行
對于多層動(dòng)畫播放順序的集合,可以使用set集合嵌套執(zhí)行
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:duration="5000"
android:propertyName="translationX"
android:valueFrom="-500"
android:valueTo="0"
android:valueType="floatType" />
<objectAnimator
android:duration="5000"
android:propertyName="translationY"
android:valueFrom="500"
android:valueTo="0"
android:valueType="floatType" />
<objectAnimator
android:duration="5000"
android:propertyName="alpha"
android:valueTo="0f" />
</set>
多set嵌套
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<objectAnimator
android:duration="5000"
android:propertyName="translationX"
android:valueFrom="-500"
android:valueTo="0"
android:valueType="floatType" />
<set>
<objectAnimator
android:duration="5000"
android:propertyName="translationY"
android:valueFrom="500"
android:valueTo="0"
android:valueType="floatType" />
<objectAnimator
android:duration="5000"
android:propertyName="alpha"
android:valueFrom="0f"
android:valueTo="1f" />
</set>
<set
android:ordering="together">
<objectAnimator
android:duration="5000"
android:propertyName="scaleX"
android:valueFrom="0.5f"
android:valueTo="1f"
android:valueType="floatType" />
<objectAnimator
android:duration="5000"
android:propertyName="scaleY"
android:valueFrom="0"
android:valueTo="0.5f"
android:valueType="floatType" />
</set>
</set>
代碼使用該動(dòng)畫集合
AnimatorSet set= (AnimatorSet) AnimatorInflater.loadAnimator(MainActivity.this,R.animator.object_anim);
set.setTarget(ivBack);
set.start();
代碼實(shí)現(xiàn)屬性動(dòng)畫
旋轉(zhuǎn)動(dòng)畫
ObjectAnimator rotation = ObjectAnimator.ofFloat(ivBack, "rotation",0,90, 0f, 180f);
rotation.setDuration(2000);
rotation.start();
透明度變換
ObjectAnimator anim = ObjectAnimator.ofFloat(ivBack, "alpha", 1.0f, 0.8f, 0.6f, 0.4f, 0.2f, 0.0f);
anim.setRepeatCount(-1);
anim.setRepeatMode(ObjectAnimator.REVERSE);
anim.setDuration(2000);
anim.start();
anim.setRepeatCount(-1);設(shè)置動(dòng)畫的循環(huán)次數(shù), ValueAnimator.INFINITE即無限循環(huán)
android:repeatMode
重復(fù)模式代咸,前提是android:repeatCount為-1
它有兩種值:”reverse”和”repeat”,第一個(gè)表示反向重復(fù)成黄,第二個(gè)為順序重復(fù)呐芥。
用組合實(shí)現(xiàn)動(dòng)畫效果也是可以的
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(ivBack, "alpha", 1.0f, 0.5f, 0.8f, 1.0f);
ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(ivBack, "scaleX", 0.0f, 1.0f);
ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(ivBack, "scaleY", 0.0f, 3.0f);
ObjectAnimator rotateAnim = ObjectAnimator.ofFloat(ivBack, "rotation", 0, 150);
ObjectAnimator transXAnim = ObjectAnimator.ofFloat(ivBack, "translationX", 100, 390);
ObjectAnimator transYAnim = ObjectAnimator.ofFloat(ivBack, "translationY", 100, 380);
AnimatorSet set = new AnimatorSet();
set.playTogether(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim);
// set.playSequentially(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim);
set.setDuration(3000);
set.start();
注:為了區(qū)分Property animation和View animation的資源文件,從Android 3.1(api 12)開始奋岁,Property animation的xml文件存在res/animator/目錄下(View animation的存在res/anim/目錄下)思瘟, animator這個(gè)名是可選的。但是如果你想要使用Eclipse ADT plugin (ADT 11.0.0+)的布局編輯器闻伶,你就必須使用res/animator/目錄滨攻,因?yàn)锳DT只在該目錄下尋找property animation的資源文件。