Android 3.0之前已有動(dòng)畫框架Animation低缩,但存在一些局限性,當(dāng)某個(gè)元素發(fā)生視圖動(dòng)畫后,其響應(yīng)事件位置還在動(dòng)畫前的地方辣恋。于是3.0之后,Google提出了屬性動(dòng)畫模软。
ObjectAnimator
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView, "translationX", 300);?
objectAnimator1.setInterpolator(new AccelerateInterpolator());?
objectAnimator1.setDuration(2000);?
objectAnimator.setRepeatCount(ValueAnimator.INFINITE);//Animation.INFINITE 表示重復(fù)多次?
objectAnimator.setRepeatMode(ValueAnimator.RESTART);//RESTART表示從頭開始伟骨,REVERSE表示從末尾倒播?
objectAnimator1.start();
第一個(gè)參數(shù):操縱的view 第二個(gè)參數(shù):操縱的動(dòng)畫屬性值 第三個(gè)參數(shù):可變數(shù)組參數(shù)
動(dòng)畫屬性值
translationX和translationY:增量控制view從它布局容器左上角坐標(biāo)偏移
ObjectAnimator.ofFloat(imageView, "translationX", 300f);?
rotation、rotationX燃异、rotationY:控制view繞支點(diǎn)進(jìn)行2D或3D旋轉(zhuǎn)
ObjectAnimator.ofFloat(imageView, "rotation", 360); scaleX携狭、scaleY:
控制view繞支點(diǎn)進(jìn)行2D縮放
ObjectAnimator.ofFloat(imageView, "scaleX", 1f, 0.5f,1f);?
alpha:控制view透明度回俐,默認(rèn)是1(不透明)逛腿,0完全透明(不可見)
ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0.5f);?
x和y:描述view在容器最終位置
可變數(shù)組參數(shù)
可以有一個(gè)到N個(gè)稀并,如果是一個(gè)值的話默認(rèn)這個(gè)值是動(dòng)畫過渡值的結(jié)束值。如果有N個(gè)值单默,動(dòng)畫就在這N個(gè)值之間過渡碘举。
動(dòng)畫監(jiān)聽
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView, "alpha", 0.5f, 1f); objectAnimator1.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) {
}});
一般我們只關(guān)心onAnimationEnd,所以Android提供了AnimatorListenerAdapter:
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView, "alpha", 0.5f, 1f); objectAnimator1.addListener(new AnimatorListenerAdapter()?
{?
@Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation);?
} });?
ValueAnimator
ValueAnimator 本身不提供任何動(dòng)畫效果雕凹,像個(gè)數(shù)值 發(fā)生器殴俱,用來產(chǎn)生具有一點(diǎn)規(guī)律數(shù)字。
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 100); valueAnimator.setTarget(imageView); ?
valueAnimator.setDuration(2000).start();?
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation)
?{?
Int value = (Integer) animation.getAnimatedValue(); //TODO use the value Toast.makeText(getApplicationContext(), "value=" + value, Toast.LENGTH_LONG).show(); } });?
PropertyValuesHolder針對(duì)同一個(gè)對(duì)象多個(gè)屬性枚抵,同時(shí)作用多種動(dòng)畫
PropertyValuesHolder propertyValuesHolder1 = PropertyValuesHolder.ofFloat("translationX", 300f);?
PropertyValuesHolder propertyValuesHolder2 = PropertyValuesHolder.ofFloat("alpha", 1f, 0.5f);?
PropertyValuesHolder propertyValuesHolder3 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);?
PropertyValuesHolder propertyValuesHolder4 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);?
ObjectAnimator.ofPropertyValuesHolder(imageView, propertyValuesHolder1, propertyValuesHolder2, propertyValuesHolder3, propertyValuesHolder4) .setDuration(5000).start();?
AnimatorSet與PropertyValuesHolder類似线欲,但AnimatorSet多了playTogether(同時(shí)執(zhí)行)、playSequentially(順序執(zhí)行)汽摹、play(objectAnimator1).with(objectAnimator2)李丰、before、after這些方法協(xié)同工作逼泣。
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0.5f); ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(imageView, "translationY", 300); ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(imageView, "scaleX", 1f, 0, 1f); AnimatorSet animatorSet = new AnimatorSet();?
animatorSet.setDuration(5000);?
animatorSet.playTogether(objectAnimator1, objectAnimator2,objectAnimator3); animatorSet.start();?
xml使用屬性動(dòng)畫
res下建立animator文件夾趴泌,然后建立res/animator/set_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:propertyName="alpha"
android:valueFrom="0.1"
android:valueTo="1.0"
android:valueType="floatType" />
調(diào)用:
Animator animator = AnimatorInflater.loadAnimator(getApplicationContext(), R.animator.set_animator);?
animator.setTarget(imageView);?
animator.start();?
動(dòng)畫組合 set標(biāo)簽,有一個(gè)orderring屬性設(shè)置為together拉庶,還有另一個(gè)值:sequentially(表示一個(gè)接一個(gè)執(zhí)行)嗜憔。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="1"
android:valueTo="0.5" />
<objectAnimator
android:duration="1000"
android:propertyName="scaleY"
android:valueFrom="1"
android:valueTo="0.5" />
View的animate方法
Android 3.0后,谷歌給View增加animate方法直接驅(qū)動(dòng)屬性動(dòng)畫氏仗。
imageView.animate() .alpha(0.5f) .y(300) .setDuration(2000)?
//api min is 16
?.withStartAction(new Runnable() { @Override public void run() { } })?
//api min is 16
.withEndAction(new Runnable() { @Override public void run() { } }).start();
?布局動(dòng)畫
設(shè)置子View過渡動(dòng)畫
LinearLayout parentLayout = (LinearLayout) findViewById(R.id.parentLayout); ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1); scaleAnimation.setDuration(2000); LayoutAnimationController layoutAnimationController=new LayoutAnimationController(scaleAnimation,0.5f); layoutAnimationController.setOrder(LayoutAnimationController.ORDER_NORMAL); parentLayout.setLayoutAnimation(layoutAnimationController);
通過Animator系列的API來控制動(dòng)畫的開始吉捶、停止和取消。
在之前的教程中皆尔,我們已經(jīng)使用過多次Animator.start這個(gè)方法呐舔。這個(gè)方法是用來讓動(dòng)畫從第一幀開始播放。該方法只是動(dòng)畫流控制方法集中的一個(gè)方法而已慷蠕,完整的方法集合如下所示:
Animator.start() // start the animation from the beginning
Animator.end() // end the animation
Animator.cancel() // cancel the animation
Animator.pause() // added in API 19; pause the animation
Animator.resume() // added in API 19; resume a paused animation
start這個(gè)方法顧名思義是用來讓動(dòng)畫從開頭開始播放的珊拼。如果動(dòng)畫設(shè)置了一個(gè)大于0的播放延遲(startDelay)魂挂,那么調(diào)用該方法后還需要等到延遲的時(shí)間過去才回開始播放钙皮。 我們有兩種停止動(dòng)畫的方法,你可以用end方法抑或cancel方法來停止一個(gè)播放著的動(dòng)畫押赊。在兩種方式中動(dòng)畫都會(huì)終止并且只有再次調(diào)用start方法才會(huì)重新開始播放每辟。兩者的區(qū)別則在于停止后動(dòng)畫所在的狀態(tài)昔头,當(dāng)你使用cancel方法來停止動(dòng)畫后,動(dòng)畫只是停止了它的時(shí)間軸影兽,動(dòng)畫的狀態(tài)會(huì)停在一個(gè)中間態(tài)(intermediate state)揭斧。如果通過end 方法來停止一個(gè)動(dòng)畫,那么動(dòng)畫會(huì)直接快進(jìn)到該動(dòng)畫最后一幀并且停止,所有的對(duì)象都會(huì)保持在動(dòng)畫最終結(jié)束后的狀態(tài)讹开。 在 Kitkat 中增加的沒有怎么被大家關(guān)注到的新API則是帶來了動(dòng)畫可以暫停和恢復(fù)的能力盅视。在那之前,一個(gè)動(dòng)畫如果被取消并且停留在當(dāng)前的中間態(tài)旦万,此時(shí)你用start方法去重啟動(dòng)畫闹击,動(dòng)畫只會(huì)從一開始重新播放。現(xiàn)在成艘,你則可以調(diào)用pause方法來暫停當(dāng)前播放中的動(dòng)畫赏半,pause也會(huì)有和cancel方法一樣的功效讓動(dòng)畫停留在中間態(tài),但是當(dāng)你使用resume 方法去恢復(fù)這個(gè)動(dòng)畫的時(shí)候淆两,動(dòng)畫會(huì)從這個(gè)狀態(tài)繼續(xù)播放下去断箫。?