在Android中的動畫主要有四種形式
1.Tween Aniamtion(變換動畫)
2.Property Animation(屬性動畫)
3.Layout Animation(布局動畫)
4.Frame Animation(逐幀動畫)
在我們的應用中適當地使用動畫,可以讓我們的應用更加美觀、柔和,對用戶來說也會更加友好。
Tween Aniamtion
Tween Animation分為四種:
Alpha:漸變透明度動畫
Scale:漸變尺寸縮放動畫
Translate:位置移動變換動畫
Rotate:旋轉動畫
共同屬性:
(1)duration:動畫持續時間。單位:毫秒
(2)reaptCount:動畫重復次數
(3)reaptMode:動畫重復模式(值:倒序重復 REVERSE,順序重復 RESTART)
(4)startOffset:動畫之間的時間間隔
(5)fillAfter:設置為true,表示動畫轉化效果在動畫結束后被應用
(6)fillBefore:設置為true,表示動畫轉化效果在動畫開始前被應用
(7)interprolator:動畫插入器(加速、減速插入器)
以上的共同屬性都可以通過set方式進行設置。
下面對這四種動畫類型一一介紹
我們首先初始化一個View,以便下面演示
ImageView img = new ImageView(this)
1.Alpha
對view的透明度進行設置的取值范圍是0.0~1.0
0.0表示完全透明 1.0表示完全不透明
Java Code:
AlphaAnimation alpha = new AlphaAnimation(0F,1F);
該構造方法中的第一個參數是初始透明度,第二個參數是最終透明度。
alpha.setDuration(1000)//設置持續時間
最后使用Vew的startAnimation()
方法開始執行動畫
img.startAnimation(alpha)//開始執行動畫
XML配置文件
在xml中編寫動畫代碼,需要在工程中的res目錄下添加anim目錄,然后在該目錄中新建一個xml文件,然后如下編寫:
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0"
android:toAlpha="1"
android:duration="1000">
</alpha>
然后在Java Code中使用AnimationUtils類的loadAnimation(Context context, int id)
將xml中的動畫文件加載進來。同樣對于View使用startAnimation()
方法即可
2.Scale
對View縮放的取值范圍是從0~
0表示消失 1表示不縮放 >1表示放大
Java Code
ScaleAnimation有三個構造方法:
public ScaleAnimation(float fromX, float toX, float fromY, float toY)//前兩個參數是ViewX方向的縮放,后兩個參數是ViewY方向的縮放
public ScaleAnimation(float fromX, float toX, float fromY, float toY,float pivotX, float pivotY)//前四個參數和第一個構造方法一樣,最后兩個參數是縮放的中心點
public ScaleAnimation(float fromX, float toX, float fromY, float toY,int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
對于第三個構造方法中前四個參數和第一個構造方法一樣,后面四個參數:pivotXType與pivotYType指縮放中心點的類型,其值在Animation類中有定義:
RELATIVE_TO_SELF//指相對自身設置縮放中心
RELATIVE_TO_PARENT//指相對于view的父View設置縮放中心
ABSOLUTE//絕對的
最后的兩個參數需使用百分比的方式設置縮放中心,即值為0~1F。
XML配置文件
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0"
android:toXScale="1"
android:fromYScale="0"
android:toYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000">
</scale>
使用XML文件配置動畫時,pivotX與pivotY既可以使用百分比方式,也可以使用dp方式
3.Translate
Java Code
Translate有兩個構造方法:
public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)//很容易理解,即X方向的移動距離,Y方向的移動距離
public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
int fromYType, float fromYValue, int toYType, float toYValue)
第二個構造方法中的fromXType與fromYType與ScaleAnimation中的pivotXType的值是一樣的,默認為相對自身的當前位置,其他參數與第一個構造方法的參數含義一樣
XML配置文件
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="100"
android:fromYDelta="0"
android:toYDelta="100"
android:duration="1000">
</translate>
比較簡單,就不做詳細介紹了。
4.Rotate
Java Code
RotateAnimation也有三個常用的構造方法:
public RotateAnimation(float fromDegrees, float toDegrees)//初始(from)的角度,結束時(to)的角度
public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,int pivotYType, float pivotYValue)
后面兩個構造方法的參數其實和上面介紹的Scale是一樣,就不做介紹了
XML配置文件
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360">
</rotate>
5.Animation中的interprolator
Animation中的interprolator最底層的接口是
public interface TimeInterpolator
他的子類有:
AccelerateInterpolator
加速插值器(動畫速率開始很慢,然后逐漸加速)
DecelerateInterpolator
減速插值器(動畫速率開始很快,然后逐漸減速)
AccelerateDecelerateInterpolator
加速減速插值器(動畫速率開始慢然后塊)
LinearInterpolator
線性插值器(最簡單的插值器,即使動畫勻速運動)
BounceInterpolator
彈跳插值器(在動畫結束時使View呈彈跳狀態)
AnticipateInterpolator
回蕩秋千插值器(開始向后蕩,然后向前蕩的插值器)
CycleInterpolator
正弦周期變化插值器(動畫循環播放特定的次數,速率改變沿著正弦曲線)
OvershootInterpolator
向前甩一定值后再回到原來位置
AnticipateOvershootInterpolator
開始的時候向后然后向前甩一定值后返回最后的值
Property Animation
屬性動畫實在API3.0之后出現的。屬性動畫相對于Tween傳統動畫具有一定的優越性,因為傳統動畫是不斷調用onDraw()方法去重繪界面來實現動畫效果,這在一定程度上必定會加大CPU負擔,從而帶來性能問題,并且傳統動畫只是重繪了界面,改變了View的顯示位置,但是對用戶的onClick等響應事件并沒有發生相應的變化,所以傳統動畫并不適于那些具有交互的動畫效果。而屬性動畫是改變View的屬性值,真真正正改變了一個View,因此屬性動畫大大改變了傳統動畫的局限性。
ObjectAnimator
ObjectAnimator是屬性動畫中比較簡單基礎的類,我們可以使用以下方法為一個View添加動畫效果。
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)
第一個參數即要添加動畫效果的View
第二個參數時屬性名稱。其實只要一個View的API中為某個屬性設置setter/getter方法,我們就可以為它添加屬性動畫,這個屬性名稱可以為"rotation"、"translateX"、"translateY"、"X"、"Y"等View屬性。
第三個參數是一個可變參數,即我們需要設置的動畫值。例如:
ObjectAnimator.ofFloat(img, "translateX", 0F, 100F);//X方向的偏移
ObjectAnimator.ofFloat(img, "translateY", 0F, 100F);//Y方向的偏移
多重動畫的添加,我們可以使用如下方式
方式一:
ObjectAnimator.ofFloat(img, "translateX", 0F, 100F).setDuration(1000).start();
ObjectAnimator.ofFloat(img, "translateY", 0F, 100F).setDuration(1000).start();
這種方式并不是先執行“translateX”動畫,再執行“translateY”動畫,而是同時執行
方式二:
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("rotation",0F,360F);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translateX",0F,100F);
ObjectAnimator.ofPropertyValuesHolder(img,p1,p2).setDuration(1000).start();
方式三:
Animator anim1 = ObjectAnimator.ofFloat(img, "translateX", 0F, 100F);
Animator anim2 = ObjectAnimator.ofFloat(img, "translateY", 0F, 100F);
AnimatorSet set = new AnimatorSet();
set.setDuration(1000);
set.playTogether(anim1,anim2);
set.start();
在AnimatorSet類中,有很多方法方便我們控制動畫的執行流程
public void playSequentially(Animator... items)//順序執行items
public Builder with(Animator anim)//與某個動畫同時執行
public Builder before(Animator anim)//在某個動畫執行之前執行anim
public Builder after(Animator anim)//在某個動畫執行后執行anim
動畫監聽事件AnimatorListener
ObjectAnimator anim = ObjectAnimator.ofFloat(root, "translateX", 0F, 100F);
anim.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){}//動畫重復時執行
});
當然有時候我們并不需要監聽動畫的這么多事件,那么我們可以使用AnimatorListenerAdapter這個抽象類,去重寫我們需要監聽的事件即可。
anim1.addListener(new AnimatorListenerAdapter(){
@Override
public void onAnimationEnd(Animator animation){
super.onAnimationEnd(animation);
}
});
Layout Animation
所謂布局動畫即添加到布局的動畫效果,并且動畫效果會影響到布局的子對象。
為布局添加動畫需要使用到LayoutAnimationController這個類,該類有兩個常用構造方法
public LayoutAnimationController(Animation animation)
public LayoutAnimationController(Animation animation, float delay)
這兩個構造比較容易理解,往構造方法中傳遞一個Animation參數即可。第二個構造方法中的delay(延遲)指子對象出現的先后延遲時間,即第一個View子對象開始出現后delay秒,第二個View子對象出現。
新建好LayoutAnimationController對象之后,使用
view.setLayoutAnimation(LayoutAnimationController controller)
這樣我們就為布局添加好了動畫效果。
LayoutAnimationController中有這樣一個方法setOrder(int order),該方法指定布局中子View出現的先后順序,API為我們制定了三個值,在LayoutAnimationController類中
ORDER_NORMAL//順序
ORDER_REVERSE//倒序
ORDER_RANDOM//隨機
為布局添加布局改變動畫
在Layout的XML配置文件中使用
android:animateLayoutChanges=["true"|"false"]
這樣就會為我們的布局添加一個系統默認的布局改變動畫效果。
當然我們也可以自定義這個動畫效果
使用view.setLayoutTransition(LayoutTransition transition)方法即為布局添加了一個默認的布局改變動畫,如果想改變這個動畫,需要使用到
public void setAnimator(int transitionType, Animator animator)
這個方法,第一個參數指布局改變的類型,在LayoutTransition 類中API為我們提供了5個值
CHANGE_APPEARING//由于主容器新增加了一個View,而導致原來的View位置發生改變時觸發的動畫
CHANGE_DISAPPEARING//由于主容器移除了一個View,而導致原來的View位置發生改變時觸發的動畫
APPEARING//View顯示時的動畫
DISAPPEARING//View消失時的動畫
CHANGING//包含上面所有的情況
XML配置文件
我們也可以在XML文件中為布局設置布局動畫
首先使用XML創建一個Tween Animation
然后使用XML通過以下語法創建一個布局動畫
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@[package:]anim/anim_resource_name"
android:delay="0.5">
</layoutAnimation>
根節點必須是layoutAnimation,android:animation指定義的Tween Animation
最后在layout布局中為布局使用android:layoutAnimation="@[package:]anim/anim_resource_name"
將我們編寫的layoutAnimation文件的文件名傳遞進去即可。
Frame Animation
這種類型的動畫,在官方文檔中是這樣介紹的:
Frame動畫是一系列圖片按照一定的順序展示的過程,和放電影的機制很相似,我們稱之為逐幀動畫。Frame動畫既可以在XML文件中定義,也可以完全編碼實現。
XML配置文件
在XML中進行定義時,文件既可以放在anim目錄中也可以放在drawable文件中。語法如下:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot=["true" | "false"] >
<item
android:drawable="@[package:]drawable/drawable_resource_name"
android:duration="integer" />
</animation-list>
animation-list作為根節點是必須的
android:oneshot若設值為true表示動畫執行一次,若設值為false表示動畫會重復執行。
每一個<item>元素表示一幀動畫,android:drawable表示一幀所對應的圖片,android:duration表示該幀所執行的時間。
Java Code
若以純編碼實現Frame動畫需要用到AnimationDrawable類,該類是Drawable的子類。
在Java代碼中我們可以使用setBackgroundResource()方法將我們XML中定義的Frame動畫設置到ImageView上
image.setBackgroundResource(R.anim.frame);
AnimationDrawable anim = (AnimationDrawable) image.getBackground();
anim.start();
如果想要停止掉動畫,只需調用anim.stop()方法即可。
還可以通過以下方式定義一個Frame動畫
AnimationDrawable frame = new AnimationDrawable();
for(int i = 0; i< 4; i++){
int id = getResources().getIdentifier("f"+i,"drawable",getPackageName());
Drawable drawable = getResources().getDrawable(id);
frame.addFrame(drawable,300);
}
frame.setOneShot(true);
img.setBackgroundDrawable(frame);
frame.start();
注意:對于AnimationDrawable不要在Activity的onCreate()方法中去掉用start()方法,因為此時窗口對象Window還沒有初始化,AnimationDrawable不能被追加到Window中的視圖對象中,所以并沒有效果。解決辦法可以是將animation的start放在一個按鈕的點擊事件或其他響應事件中,也可以在onWindowFocusChanged方法中開始執行動畫,onWindowFocusChanged方法會在窗口初始化完成后被執行,在onCreate()方法之后執行。