Android的動畫用得好的話可以產(chǎn)生意想不到的效果排吴,用得不好的話就會使程序產(chǎn)生Crash或者視圖加載緩慢
- Android動畫分類
- Android視圖動畫
- View動畫
- 幀動畫
- Android屬性動畫
- Android視圖動畫
View動畫就是通過對場景里面的對象不斷地做圖像變換(平移幕袱、縮放匪蝙、旋轉(zhuǎn)粮宛、透明度)從而產(chǎn)生一種漸進式動畫
幀動畫是通過順序播放一系列圖像從而產(chǎn)生動畫效果箱蝠,可以簡單的理解為圖片切換泌绣,顯然這種方式很容易造成OOM
屬性動畫是通過動態(tài)的改變對象的屬性從而達到動畫的效果
下面來介紹動畫的實現(xiàn)
-
View動畫和幀動畫的實現(xiàn)與方法
View動畫包括四種分別是:TranslateAnimation述暂、ScaleAnimation、RotateAnimation叨橱、AlphaAnimation典蜕,View動畫的實現(xiàn)比較簡單可以通過在XML文件中創(chuàng)建也可以通過在代碼中實現(xiàn),View動畫是比較基礎的動畫效果罗洗,建議先把這類動畫效果掌握在去深入了解愉舔。
先來看一下通過XML文件實現(xiàn)的動畫
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:fromAlpha="0.1" android:toAlpha="1.0" android:duration="2000"/> <rotate android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:duration="500"/> <scale android:fromXScale="0.0" android:toXScale="1.0" android:fromYScale="0.0" android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="500"/> <translate android:fromXDelta="10" android:toXDelta="100" android:fromYDelta="10" android:toYDelta="100"/> </set>
也可以通過代碼來實現(xiàn)
//Alpha AlphaAnimation alphaAnimation = new AlphaAnimation(0,1); alphaAnimation.setDuration(300); this.startAnimation(); //Rotate RotateAnimation rotateAnimation = new RotateAnimation(0f, 360f); rotateAnimation.setDuration(1000); this.startAnimation(rotateAnimation); //Scale Animation scaleAnimation = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f); scaleAnimation.setDuration(500); this.startAnimation(scaleAnimation); //Translate Animation translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f); translateAnimation.setDuration(1000); this.startAnimation(translateAnimation);
另外通過Animation的setAnimationListener方法可以給View動畫添加過程監(jiān)聽
public static interface AnimationListener{ void onAnimationStart(Animation animation); void onAnimationEnd(Animation animation); void onAnimationRepeat(Animation animation); }
幀動畫一般不宜使用尺寸較大的圖片容易引起OOM
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/image1" android:duration="500"/> <item android:drawable="@drawable/image2" android:duration="500"/> <item android:drawable="@drawable/image3" android:duration="500"/> </set>
將上面的Drawable最為view的背景通過Drawable來播放動畫
this.setBackgroundResource(R.drawable.frame_animation); AnimatioinDrawable drawable = (AnimationDrawable)this.getBackground(); drawable.start();
-
屬性動畫的實現(xiàn)與方法
Animator框架中使用的最多的就是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator進行更精細的控制伙菜,只控制一個對象的一個屬性值轩缤。而使用多個ObjectAnimator組合到一個AnimatorSet形成一個動畫。屬性動畫通過調(diào)用屬性的set和get方法控制一個View的屬性值,可以實現(xiàn)所有的動畫效果典奉。
-
ObjectAnimator
創(chuàng)建一個ObjectAnimator只需要通過他的靜態(tài)工廠類直接返回一個ObjectAnimator對象躺翻,參數(shù)包括一個對象和對象的屬性,但是這個屬性必須含有get和set函數(shù)卫玖,內(nèi)部會通過Java反射機制來調(diào)用set函數(shù)修改對象屬性值公你。
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", 300); animator.setDuration(300); animator.start();
常用的屬性值有:translationX、translationY假瞬、rotation陕靠、rotationX、rotationY,scaleX,scaleY,pivotX,pivotY,alpha
如果這個屬性沒有get和set方法脱茉,則可以通過自定義一個屬性類和包裝類來為這個屬性增加get剪芥、set方法或者通過ValueAnimator來實現(xiàn) private static class WrapperView{ private View mTarget; public WrapperView(View target){ mTarget = target; } public int getWidth(){ return mTarget.getLayoutParams.width; } public int getWidth(int width){ mTarget.getLayoutParams.width = width; mTarget.requestLayout(); } }
通過以上的包裝類就可以調(diào)用get和set方法了,代碼如下:
ViewWrapper wrapper = new ViewWrapper(mButton);
ObjectAnimator.ofInt(wrapper,"width", 500).setDuration(5000).start();
ObjectAnimator 還給我提供了一系列的監(jiān)聽方法:
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.5f);
anim.addListener(new AnimatorListener(){
@Override
public void onAnimationStart(Animator animation) {
//動畫開始的操作
}
@Override
public void onAnimationEnd(Animator animation) {
//TODO 動畫結束的操作
}
@Override
public void onAnimationCancel(Animator animation) {
//TODO 動畫取消的操作
}
@Override
public void onAnimationRepeat(Animator animation) {
//TODO 動畫重復的操作
}
});
但是大部分時間我們只是關心onAnimatorEnd()事件琴许,所以Android提供了一個AnimatorListenerAdapter來進行必要的監(jiān)聽:
anim.addListener(new AnimatorListenerAdapter(){
@Override
public void onAnimatorEnd(Animator animator){
}
});
- PropertyValuesHolder
PropertyValuesHolder針對一個對象的多個屬性税肪,要同時作用多種動畫;
PropertyValuesHolder pyh1 = PropertyValuesHolder.ofFloat("translationX", 3000);
PropertyValuesHolder pyh2 = PropertyValuesHolder.ofFloat("translationX", 3000);
PropertyValuesHolder pyh3 = PropertyValuesHolder.ofFloat("translationX", 3000);
分別用PropertyValuesHolder對象控制tranX榜田,scaleX益兄,scaleY這三個屬性,最后調(diào)用ObjectAnimator.ofPropertyValuesHolder方法實現(xiàn)多屬性動畫的共同作用箭券。
- ValueAnimator
ValueAnimation是ObjectAnimation類的父類,ValueAnimator本身不提供任何的動畫效果净捅,但他更像一個數(shù)值發(fā)生器,用來產(chǎn)生一定規(guī)律的數(shù)字辩块,讓調(diào)用者來控制動畫的實現(xiàn)過程蛔六,他的方法如下:
ValueAnimator animator = ValueAnimator.ofFloat(0, 100);
animator.setTarget(view);
animator.setDuration(1000).start();
animator.addUpdateListener(new AnimatorUpdateListener(){
@Override
public void onAnimatorUpdate(ValueAnimator animation){
Float value = (Float)animation.getAnimatedValue();
}
});
- AnimatorSet
對于一個屬性同時作用于多個屬性動畫效果,前面說的可以用PropertyValuesHolder實現(xiàn)废亭,而AnimatorSet同樣也可以實現(xiàn)這樣的效果国章,而且順序控制的更為精準,代碼如下:
ObjectAnimator animator1 = ObjectAnimator.ofFolat(view, "translationX", 300f);
ObjectAnimator animator2 = ObjectAnimator.ofFolat(view, "scaleX", 1f, 0f, 1f);
ObjectAnimator animator3 = ObjectAnimator.ofFolat(view, "scaleY", 1f, 0f, 1f);
AnimatorSet set = new AnimatorSet();
set.setDuration(1000);
set.playTogether(animator1, animator2, animator3);
set.start();
AnimatorSet通過playTogether(),playSequentially(),animSet.play(),with(),before(),after()這些方法來控制多個動畫的協(xié)同工作方式豆村,從而做到對動畫播放順序的精確控制捉腥。
-
在XML中使用屬性動畫
<?xml version='1.0' encoding='utf-8'?> <objectAnimator xmlns:android='http://schemas.android.com/apk/res/android' android:duration='2000' android:propertyName='rotationX' android:valueFrom='0' android:valueTo='90' android:valueType='floatType' />
在程序中使用XML中定義的屬性動畫
public void scaleX(View view){
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);
anim.setTarget(view);
anim.start();
}
- Interpolator(插值器)
我們看一下插值器的定義:插值器定義了動畫變化的速率,提供不同的函數(shù)定義變化值相對于時間的變化規(guī)則你画,可以定義各種各樣的非線性變化函數(shù),比如加速桃漾、減速坏匪。他就是一個可以讓我們的動畫速度變化的值。