Android中的动画
學習內容
??幀動畫
??補間動畫
??動畫方式切換組件
能力目標
??掌握Android中動畫的基本概念及分類
??熟練掌握幀動畫的實現
??熟練掌握各種補間動畫的實現
??掌握如何使用動畫方式實現組件之間的切換效果
本章簡介
在Android程序設計過程中,除了使用簡單的按鈕、文本框等簡單控件來構建基本界面,我們還可以通過為界面添加動畫效果,使得界面更加變得更加絢麗,更加吸引人。Android平臺也提供了一套完整的動畫框架,使得開發者可以用它開發出各種動畫效果。
本章主要介紹Android系統中的動畫:幀動畫和補間動畫。其中幀動畫使用AnimationDrawable來實現,在本質上是將多個圖像以相同或不同的時間間隔進行切換來實現動畫。補間動畫需要指定動畫開始和結束狀態,然后由系統自動生成中間狀態的圖像,它包括移動、縮放、旋轉、透明度的變化等。除此之外我們還將學習Android默認提供的accelerate_interpolator、decelerate_interpolator、accelerate_decelerate_interpolator等多種動畫渲染器。
2.1?Android中的動畫
Android中的Animations動畫效果多種多樣,其中包括旋轉、縮放、淡入淡出等,這些效果可以應用于絕大多數的控件(圖片、按鈕、文本)。總的來說,默認Android系統主要提供以下兩類動畫:
??幀動畫(Frame-By-Frame?Animations):通過順序播放事先做好的圖像來實現動畫效果,和電影相似。
??補間動畫(Tweened Animations):通過對場景里的對象不斷進行圖像變換(平移、縮放、旋轉)來產生動畫效果。具體來講,Tween動畫是通過預先定義一組指令(這組指令指定了圖形變換類型、觸發時間、持續時間等),程序沿著時間軸執行這些指令來實現動畫效果。
?
2.2?幀動畫
在Android系統中大多數免費應用都會在界面中添加廣告以取得收入,而多數廣告都如我們經常看到的GIF圖片那樣,幾張不同的圖片不斷變換以增加廣告內容的充實度,而這里就需要我們使用幀動畫技術來實現這些效果。
幀動畫實際上是由若干個以一定的時間間隔進行切換的圖像組成的。比如電影的原理就類似于幀動畫,一般電影是每秒25幀。即,電影在每秒鐘之內會以相等的時間間隔連續播放25幅靜態畫面,由于人的視覺暫留,在這樣的播放頻率下,看起來這些畫面好像是連續的。在第一章中我們在onDraw()方法中使用invalidate()方法不斷地刷新View的方式實現的旋轉動畫,這種情況下,是不斷地畫出動畫中的每一幀圖像,它其實也相當于幀動畫。
要在Android中實現幀動畫,首先需要在res/anim目錄下創建一個后綴為.xml的動畫文件。然后在這個文件中指定動畫中的靜態圖像和每一張靜態圖像的停留時間,這個時間的單位是毫秒。為了讓用戶看起來舒服,一般可以將所有的圖像停留時間設為同一個值。動畫文件的一般形式如下。
<animation-list?android:oneshot="false"
xmlns:android="http://schemas.android.com/apk/res/android">?
<item?android:duration="500"?android:drawable="@drawable/a1"/>?
<item?android:duration="500"?android:drawable="@drawable/a2"/>?
……
</animation-list>
一般情況下,動畫文件由一個<animation-list>標簽和若干個<item>標簽組成。其中<animation-list>標簽的android:oneshot屬性取值為true時表示動畫只運行一遍,為false時動畫會循環播放,這個屬性是可選的,默認值是false。<item>標簽的android:drawable屬性 ???用來指定動畫中靜態圖像資源的ID,android:duration用來指定每個圖像的停留時間,這兩個屬性都是必選的,缺一不可。
編寫完動畫文件之后,就需要裝載動畫文件,并創建AnimationDrawable對象。AnimationDrawable是Drawable的子類,它在Drawable的基礎之上提供了控制動畫的功能。
實現幀動畫的基本步驟是:
(1)?在drawable中插入一系列的圖片,注意這里面圖片的命名最好要有規律可循,以方便編程使用,例如我這里面的命名是a1、a2……。
(2)?在res/anim文件夾當中創建一個xml類型的文件,將所有幀都列出來以定義Animations動畫序列,在此處可以通過oneshot設置動畫是否重復播放。
?
示例2.1:
實現GIF動畫的播放效果。
在屏幕上提供一個ImageView和四個Button,當用戶單擊這些Button按鈕時,依次實現“開始動畫”、“停止動畫”、“運行一次動畫”、“代碼中添加動畫”的功能。其中ImageView組件的作用是按照我們在動畫文件中設置的順序顯示res/drawable目錄下的靜態圖片。整個程序運行的效果和GIF圖像基本一樣。整下程序的運行效果如下圖2.1.1和圖2.1.2所示:
?
?
?
?
(1)編寫動畫文件代碼如下:
<animation-list?android:oneshot="false"
xmlns:android="http://schemas.android.com/apk/res/android">?
?
<item?android:duration="500"?android:drawable="@drawable/a1"/>?
<item?android:duration="500"?android:drawable="@drawable/a2"/>?
<item?android:duration="500"?android:drawable="@drawable/a3"/>?
<item?android:duration="500"?android:drawable="@drawable/a4"/>?
<item?android:duration="500"?android:drawable="@drawable/a5"/>?
<item?android:duration="500"?android:drawable="@drawable/a6"/>?
<item?android:duration="500"?android:drawable="@drawable/a7"/>?
<item?android:duration="500"?android:drawable="@drawable/a8"/>
</animation-list>
(2)編寫程序布局文件,在布局文件中只是提供一個id為imageViewId的ImageView組件和四個id分別為btn1、btn2、btn3、btn4的Button組件。
(3)編寫Activity類,實現功能代碼如下:
public?class?FrameByFrameActivity extends?Activity {
private?ImageView imageView?=null;
private?AnimationDrawable drawable?= null;
????@Override
????public?void?onCreate(Bundle savedInstanceState) {
????????super.onCreate(savedInstanceState);
????????setContentView(R.layout.framebyframe);
????????
????????imageView?= (ImageView) findViewById(R.id.imageViewId);
????????
????????//開始動畫
????????Button btn = (Button) findViewById(R.id.btn1);
????????btn.setOnClickListener(new?View.OnClickListener() {
public?void?onClick(View v) {
//裝載動畫布局文件
imageView.setBackgroundResource(R.anim.framebyframe);
//構建動畫
AnimationDrawable drawable = null;
drawable=(AnimationDrawable) imageView.getBackground();
//開始播放動畫
drawable.start();
}
});
????????//停止動畫
????????Button btn2 = (Button) findViewById(R.id.btn2);
????????btn2.setOnClickListener(new?View.OnClickListener() {
public?void?onClick(View v) {
drawable.stop();
}
});
????????
????????//運行一次動畫
????????Button btn3 = (Button) findViewById(R.id.btn3);
????????btn3.setOnClickListener(new?View.OnClickListener() {
public?void?onClick(View v) {
drawable.setOneShot(true);
drawable.start();
}
});
????????//添加動畫
????????Button btn4 = (Button) findViewById(R.id.btn4);
????????btn4.setOnClickListener(new?View.OnClickListener() {
public?void?onClick(View v) {
//裝載動畫布局文件
?
//AnimationDrawable對象用來表示Frame動畫
AnimationDrawable frameDrable = new?AnimationDrawable();
Drawable drawable = null;
//裝載資源
for(int?i = 1 ; i <10 ;i++){
int?id = getResources().getIdentifier("a"+i, "drawable", getPackageName());
drawable = getResources().getDrawable(id);
frameDrable.addFrame(drawable, 1000);//把每一幀要顯示的內容添加進去
}
//設置動畫不重復播放
frameDrable.setOneShot(false);
imageView.setBackgroundDrawable(frameDrable);
//開始播放動畫
frameDrable.start();
}
});
????????
????}
}
?
在btn1按鈕的單擊事件中,我們實現了動畫文件的裝載、AnimationDrawable的構建及動畫的播放功能。
除了示例代碼中使用ImageView的setBackgroundResource()方法來裝載動畫文件,并通過ImageView的getBackground()方法獲得AnimationDrawable對象實現動畫效果之外,我們還可以使用getDrawable()方法來裝載動畫文件,代碼如下:
AnimationDrawable drawable =
(AnimationDrawable) getResources().getDrawable(R.anim.framebyframe);
imageView.setBackgroundDrawable(drawable);
在btn4按鈕的單擊事件中,我們先通過new關鍵字聲明了一個AnimationDrawable對象,然后利用Java代碼通過循環的方式為這個對象添加了一系列的靜態圖片。最后調用start()方法讓其運動起來。
通過上述代碼我們會發現,所有對幀動畫的控制都是通過AnimationDrawable實現的。本示例程序中用到的AnimationDrawable中與幀動畫有關的方法如下:
??start():開始播放動畫
??stop():停止播放動畫
??void setOneShot(boolean ?b):
設置是否只播放一遍幀動畫。這個方法的參數與動畫文件中的<animation-list>標簽的android:oneshot屬性值的含義相同。
??void ?addFrame(Drawable?frame, int duration)
向AnimationDrawable對象中添加新的幀。其中參數frame是一個Drawable對象,表示要添加的幀,該參數可以是靜態圖像,也可以是另一個動畫。參數duration表示幀動畫的停留時間,如果新添加的幀是動畫,那么這停留時間就是新添加的動畫可以播放的時間,如果到了停止時間,不管新添加的動畫是否播放完,都會切換到下一個靜態圖像或動畫。
2.3?補間動畫
通過上述的幀動畫(Frame-By-Frame?Animations)技術,我們可以方便的制作出如flash般的動畫效果,只需要我們準備好每一幀動畫所需要的畫面,然后按照組織好的順序使其順序播放,即可達到動畫片似的效果,但是,如果僅僅是一個物體的簡單移動,放大縮小等功能,我們依然需要為其準備不同時刻的靜態畫面,按照電影一秒內播放25幀的速度,四秒時長的動畫效果我們就需要為其準備多達100張靜態圖片,這樣看來依然過于繁瑣,而對于這種簡單的移動、放大縮小、旋轉等動畫效果,安卓系統也為我們提供了更加方便的動畫生成技術,我們稱之為補間動畫(Tweened Animations)。
補間動畫(Tweened Animations)是指在制作動畫過程中,開發者只用定義動畫的開始、結束等等關鍵幀信息,中間的變化效果由系統自動生成,所以稱之為補間動畫。
對于圖像的簡單移動、旋轉、縮放等,都可以通過補間動畫來實現。然而,當圖像過于復雜時,由于系統無法預料下一幅畫面的樣子,此時不宜采用補間動畫,要實現動畫效果只能采用幀動畫的形式。
因為補間動畫只需要提供兩幀圖像(第一幀和最后一幀),并指定動畫的持續時間即可。所以補間動畫最大的優點是節省硬盤空間。
Android中使用Animation類代表抽象的動畫類,它包含以下幾個子類:
??TranslateAnimation:位移變化的動畫,創建該動畫時只要指定動畫開始時的位置(以X、Y坐標來表示)、結束時的位置(以X、Y坐標來表示),并指定動畫持續的時間即可。
??RotateAnimation:旋轉動畫,創建該動畫時只要指定動畫開始時的旋轉角度、結束時的旋轉角度,并指定動畫持續的時間即可。由于旋轉時以不同點為中心時旋轉效果并不相同,因此指定旋轉動畫時還要指定“旋轉中心”的坐標。
??ScaleAnimation:縮放動畫,創建該動畫時要指定動畫開始時的縮放比(以X、Y軸的縮放參數表示)、結束時動畫的縮放比以X、Y軸的縮放參數表示),并指定動畫持續的時間。由于旋轉時以不同點為中心時縮放效果并不相同,因此指定縮放動畫時還要指定“縮放中心”的坐標。
??AlphaAnimation:透明度改變動畫,創建該動畫時需要指定動畫開始時的透明度、結束時的透明度和動畫持續時間,其中透明度的變化范圍是1~0。
在本節中我們將通過具體的案例深入學習Android系統默認提供的移動、縮放、旋轉和透明四種補間動畫效果。
2.3.1?移動補間動畫
《水果忍者》也許很多同學都玩過,游戲中玩家需要用手指模擬武士刀將上拋起的各種水果切開,那么這種水果上下移動的動畫效果如何實現呢?這里我們就可以使用移動補間動畫來實現。
移動是最常見的動畫效果,可以通過配置文件或Java代碼文件來實現。
示例2.2
上下跳動的小球。
在手機屏幕上顯示一下上下移動的小球,用來模擬物體的自由下落:當小球從上到下移動時呈現加速狀態,從下到上移動時呈現減速狀態。
補間動畫文件放在res/anim目錄中,在動畫文件中通過<translate>標簽設置移動的效果。本示例用到兩個動畫渲染器:accelerate_interpolator、decelerate_interpolator。首先定義具體動畫的文件。
translatescaletop.xml定義從下到上移動,減速效果。
<?xml?version="1.0"?encoding="utf-8"?>
<translate?xmlns:android="http://schemas.android.com/apk/res/android"
????android:interpolator="@android:anim/accelerate_interpolator"
????android:fromXDelta="0"
????android:toXDelta="0"
????android:fromYDelta="250"
????android:toYDelta="0"
????android:duration="2200"?/>
translatebottom.xml定義從上到下移動,加速效果。
<?xml?version="1.0"?encoding="utf-8"?>
<translate?xmlns:android="http://schemas.android.com/apk/res/android"
????android:interpolator="@android:anim/?decelerate_interpolator"
????android:fromXDelta="0"
????android:toXDelta="0"
????android:fromYDelta="0"
????android:toYDelta="250"
android:duration="2200"?/>
<translate>標簽中設置了幾個屬性,這些屬性的含義如下:
??android:interpolator:表示動畫渲染器, Android系統一共為我們提供了linear_interpolator、accelerate_interpolator(動畫加速器)、decelerate_interpolator(動畫減速器)和accelerate_decelerate_interpolator(動畫加速減速器)四種動畫渲染器,其中動畫加速減速器使動畫在開始和結束時速度很慢,但在前半部分開始加速,后半部分開始減速。
??android:fromXDelta:動畫起始位置的橫坐標。
??android:toXDelta:動畫結束位置的橫坐標。
??android:fromYDelta:動畫起始位置的縱坐標。
??android:toYDelta:動畫結束位置的縱坐標。
??android:duration:動畫持續的時間。
Activity類代碼如下:
public?class?BallAnimationsActivity extends?Activity implements?AnimationListener {
private?ImageView imageView?= null;
private?Animation animationBottom;//從上到下
private?Animation animationTop;//從下到上
?
@Override
protected?void?onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ballanimations);
?
imageView?= (ImageView) findViewById(R.id.imageview);
Button button = (Button) findViewById(R.id.button);
?
button.setOnClickListener(new?OnClickListener() {
@Override
public?void?onClick(View v) {
imageView.startAnimation(animationBottom);
}
});
?
animationBottom?= AnimationUtils.loadAnimation(this, R.anim.transloatebottom);
animationTop?= AnimationUtils.loadAnimation(this, R.anim.transloatetop);
animationBottom.setAnimationListener(this);
animationTop.setAnimationListener(this);
}
?
@Override
public?void?onAnimationStart(Animation animation) {
//動畫開始時調用
}
?
@Override
public?void?onAnimationEnd(Animation animation) {//動畫結束時調用
//根據當前顯示的動畫決定下次顯示哪一個動畫
if?(animation.hashCode() == animationBottom.hashCode())
imageView.startAnimation(animationTop);
else?if?(animation.hashCode() == animationTop.hashCode())
imageView.startAnimation(animationBottom);
}
?
@Override
public?void?onAnimationRepeat(Animation animation) {//動畫循環時調用
?
}
}
代碼解析:
其中ballanmimations.xml是一個只提供了一個包含id為imageView的ImageView組件和一個id為btn的Button組件的布局文件。
補間動畫有動畫開始、動畫結束、動畫循環3種狀態:,我們可以通過android.view.animation.Animation.AnimationListener接口實現對這三種狀態的監聽。這個接口中定義的三個方法:onAnimationStart()、onAnimationEnd()、onAnimationRepeat()分別在動畫開始、動畫結束和動畫循環時被調用。
將動畫文件應用到指定的組件上,除了可以使用示例中調用startAnimation()方法外,還可以使用如下方法:
imageView.setAnimation(animationBottom);
animation.start();
程序中裝載動畫文件時用到了如下方法:
Animation??AnimationUtils.loadAnimation(Context?context, int id)
從資源文件中裝載動畫。其中id表示動畫文件的資源ID。
單擊【開始動畫】按鈕后,小球就會在垂直方向上按照我們的設置上下移動,效果如下圖2.1.3所示。
?
2.3.2?縮放補間動畫
在《憤怒的小鳥》的游戲中,當我們需要讓小鳥由遠及近或者由近及遠飛翔時,那么它應該是出現一種由小變大或者由大變小的狀態來模擬距離的改變,而這種動畫的實現,我們就需要用到下面的縮放補間動畫技術。
示例2.3:
實現一個可以跳動的心.跳動實際上就是不斷地將心型的圖像放大和縮小,因此本示例需要兩個動畫文件,一個表示放大后的狀態,一個表示縮小后的狀態。
心臟放大的配置文件scalelarge.xml代碼如下:
<scale?xmlns:android="http://schemas.android.com/apk/res/android"
????android:duration="500"
????android:fromXScale="0.2"
????android:toXScale="1.0"
????android:fromYScale="0.2"
????android:toYScale="1.0"?
????android:interpolator="@android:anim/decelerate_interpolator"
????android:pivotX="50%"
????android:pivotY="50%"?/>
心臟縮小的配置文件scalesmall.xml代碼如下:
<scale?xmlns:android="http://schemas.android.com/apk/res/android"
????android:duration="500"
????android:fromXScale="1.0"
????android:fromYScale="1.0"
????android:interpolator="@android:anim/accelerate_interpolator"
????android:pivotX="50%"
????android:pivotY="50%"
????android:toXScale="0.2"
android:toYScale="0.2"?/>
<scale>標簽中設置了幾個屬性,這些屬性的含義如下:
??android:fromXScale:表示沿X軸縮放的起始比例。
??android:toXScale:表示沿X軸縮放的結束比例。
??android:fromYScale:表示沿Y軸縮放的起始比例。
??android:toYScale:表示沿Y軸縮放的結束比例。
??android:pivotX:表示沿X軸方向上縮放的中心點位置。
??android:pivotY:表示沿Y軸方向上縮放的中心點位置。
接下來在Activity中編寫功能實現代碼。
public?class?HeartScaleActivity extends?Activity implements?AnimationListener {
private?Animation large;
private?Animation small;
private?ImageView imageView;
?
@Override
public?void?onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.heartanimations);
imageView?= (ImageView) findViewById(R.id.imageview);
large?= AnimationUtils.loadAnimation(this, R.anim.scalelarge);
small?= AnimationUtils.loadAnimation(this, R.anim.scalesmall);
large.setAnimationListener(this);
small.setAnimationListener(this);
imageView.startAnimation(small);
}
@Override
public?void?onAnimationEnd(Animation animation) {
if?(animation.hashCode() == large.hashCode())
imageView.startAnimation(small);
else
imageView.startAnimation(large);
?
}
?
@Override
public?void?onAnimationRepeat(Animation animation) {
}
?
@Override
public?void?onAnimationStart(Animation animation) {
}
}
其中heartanmimations.xml是一個只提供了一個包含id為imageView的ImageView布局文件。
任意選取兩個時刻,程序運行效果如下圖2.1.4和圖2.1.5所示。
?
圖2.1.4 心形放大的圖像
?
圖2.1.5 心型縮小圖像
2.3.3?旋轉補間動畫
在游戲中,很多時候我們要實現某個物品按照某個點不斷旋轉的效果,例如《瘋狂的小鳥》游戲中,當小鳥撞上障礙物時,就會不斷旋轉著跌落下去,這里小鳥的運動顯然除了旋轉,還有一個自由落體的運動過程,而單就旋轉這種簡單的動畫來說,我們就可以運用Android系統中提供的旋轉補間動畫來實現。
示例2.4:模擬實現月球環繞地球旋轉的效果,如下圖2.1.6所示。
?
圖2.1.6 地月系
定義地球自轉動畫的xml文件earth.xml內容如下:
<rotate?xmlns:android="http://schemas.android.com/apk/res/android"
????android:duration="20000"
????android:fromDegrees="0"
????android:pivotX="50%"
????android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="restart"
????android:toDegrees="360"?/>
定義月球圍繞地球旋轉動畫的xml文件moon.xml內容如下:
<rotate?xmlns:android="http://schemas.android.com/apk/res/android"
????android:duration="10000"
????android:fromDegrees="0"
????android:pivotX="200%"
????android:pivotY="300%"
????android:repeatCount="infinite"
????android:repeatMode="restart"
????android:toDegrees="360"?/>
<rotate>標簽中設置了幾個屬性,這些屬性的含義如下:
??android: fromDegrees:表示旋轉的起始角度。
??android:toDegrees:表示旋轉的結束角度。
??android:repeatCount:用來設置旋轉的次數。當取值為0時(默認),從0度旋轉到360度,動畫就會停止;如果屬性值為N(N>0),動畫會不停地顯示N+1次;當取值為infinite或-1時,動畫會永不停地運行下去。
??android:repeatMode:用來設置旋轉的模式。默認值是restart,該屬性值只有當android:repeatCount設置成大于0的數或infinite時才起作用。該屬性取值reverse時表示偶數次顯示動畫時會做與動畫文件定義的方向相反的動作。
??pivotX:旋轉支點橫坐標。
??pivotY:旋轉支點縱坐標。
pivotX和pivotY的取值有兩種:float或百分數,分別是相對于物體左(上)邊距的像素表示或相對于物體左(上)邊距的百分數表示。旋轉支點坐標的具體計算公式如下:
假如物體原來的坐標是(x0,y0),采用像素形式時pivotX=x1,pivotY=y1,采用百分比形式時pivotX=n1%,pivotY=n2%。那么最終旋轉中心的坐標為(x0+x1,y0+y1)或(x0+width*n1%,y0+height*n2%),其中width和height分別指圖片的寬度和高度。
?
Activity類代碼:
public?class?EarthMoonActivity extends?Activity {
@Override
public?void?onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.earthmoon);
ImageView moon = (ImageView) findViewById(R.id.moon);
ImageView earth = (ImageView) findViewById(R.id.earth);
Animation moonAnimation = AnimationUtils.loadAnimation(this, R.anim.moon);
Animation earthAnimation = AnimationUtils.loadAnimation(this, R.anim.earth);
moon.startAnimation(moonAnimation);
earth.startAnimation(earthAnimation);
}
}
其中布局文件earthmoon.xml采用絕對布局,在其中放置了兩個id分別為moon和earth的ImageView組件,詳細代碼如下:
<?xml?version="1.0"?encoding="utf-8"?>
<AbsoluteLayout?xmlns:android="http://schemas.android.com/apk/res/android"
????android:layout_width="fill_parent"
????android:layout_height="fill_parent"
????android:gravity="center_vertical"
????android:orientation="vertical"?>
????<ImageView
????????android:id="@+id/moon"
????????android:layout_width="50dp"
????????android:layout_height="50dp"
????????android:layout_x="50dp"
????????android:layout_y="50dp"
????????android:src="@drawable/moon"?/>
????<ImageView
????????android:id="@+id/earth"
????????android:layout_width="80dp"
????????android:layout_height="80dp"
????????android:layout_x="120dp"
????????android:layout_y="200dp"
????????android:src="@drawable/ball" />
</AbsoluteLayout>
運行程序,會發現代表月亮的圖片會按照逆時針方向圍繞著地球旋轉,而地球本身也會按照順時針的方向圍繞著自身的地軸旋轉。
2.3.4?透明補間動畫
很多游戲在設計時,都會讓已經被消滅的敵人慢慢地在屏幕中變成透明狀,最后完全消失,以避免擠占寶貴的屏幕顯示資源,而在Android系統中,這種效果同樣十分簡單,只需要運用我們下面提到的這種技術即可——透明補間動畫。
示例2.5:
通過改變圖片透明度實現屏幕上對象逐漸消失的效果。
動畫效果定義文件alpha.xml內容如下:
<?xml?version="1.0"?encoding="utf-8"?>
<set?xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:shareInterpolator?=?"true">
<alpha
android:fromAlpha="1.0"
android:toAlpha?=?"0.0"
android:startOffset=?"200"
android:duration?=?"3000"
/>
</set>
這個文件定義中各個屬性含義如下:
??android:fromAlpha:表示起始透明度,取值在0.0~1.0之間,其中0.0表示完全透明,1.0表示完全不透明。
??android:toAlpha:表示結束透明度。
??android:shareInterpolator = "true":設置內部所有的控件共享Interpolator。
??android:startOffset:開始時間偏移量,指在動畫開始前等待的時間。
布局文件代碼:
<?xml?version="1.0"?encoding="utf-8"?>
<AbsoluteLayout?xmlns:android="http://schemas.android.com/apk/res/android"
????android:layout_width="fill_parent"
????android:layout_height="fill_parent"
????android:gravity="center_vertical"
????android:orientation="vertical"?>
????<ImageView
????????android:id="@+id/earth"
????????android:layout_width="80dp"
????????android:layout_height="80dp"
????????android:layout_x="120dp"
????????android:layout_y="100dp"
????????android:src="@drawable/ball"?/>
</AbsoluteLayout>
Activity類代碼:
public?class?EarthMoonActivity extends?Activity {
@Override
public?void?onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.earthmoon);
ImageView earth = (ImageView) findViewById(R.id.earth);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha);
earth.startAnimation(animation);
}
}
?
某一時刻程序的運行效果如下圖2.1.7所示:
?
圖2.1.7 透明效果
2.4?動畫方式切換各組件
最后讓我們將上述提到的幾種技術融合在一起,運用到我們的Android組件中,為Android系統組件的切換提供絢麗的動畫效果。
凡是使用過Android手機的用戶,都一定會被它里面的程序組件之間的切換效果所吸引,比如Android系統自帶的看圖軟件在各圖片之間切換時的過渡效果。本節課中我們就借助android.widget.ViewFliper類來模擬實現這種過渡效果。
示例2.6:
實現Android中查看圖片時的過渡效果。
具體效果如下圖2.1.8和2.1.9所示,第一種效果是移動切換,第二種效果是淡入淡出切換。
?
圖2.1.8 水平移動切換
?
?
圖2.1.9 淡入淡出切換
本示例程序使用布局文件layout1.xml、layout2.xml、layout3.xml定義了3個View,每一個View中都包含一個用來顯示圖像的ImageView組件。當用戶觸摸第一個圖像時,會以水平向左移動的方式切換到第二個圖像,觸摸第二個圖像時會以淡入淡出的方式切換到第三個圖像(通過透明度補間動畫實現)。
水平移動向左切入的動畫文件translatein.xml的內容如下:
<translate?xmlns:android="http://schemas.android.com/apk/res/android"
????android:duration="3000"
????android:fromXDelta="320"
????android:fromYDelta="0"
????android:interpolator="@anim/linear_interpolator"
????android:toXDelta="0"
????android:toYDelta="0"?/>
水平移動向左切出的動畫文件translateout.xml內容如下:
<translate?xmlns:android="http://schemas.android.com/apk/res/android"
????android:duration="3000"
????android:fromXDelta="0"
????android:fromYDelta="0"
????android:interpolator="@anim/linear_interpolator"
????android:toXDelta="-320"
????android:toYDelta="0"?/>
淡入淡出動畫的淡入效果文件alphain.xml的內容如下:
<alpha?xmlns:android="http://schemas.android.com/apk/res/android"
????android:duration="2000"
????android:fromAlpha="0"
????android:interpolator="@android:anim/accelerate_interpolator"
????android:toAlpha="1"?/>
淡入淡出動畫的淡出效果文件alphaout.xml的內容如下:
<alpha?xmlns:android="http://schemas.android.com/apk/res/android"
????android:duration="2000"
????android:fromAlpha="1"
????android:interpolator="@android:anim/accelerate_interpolator"
android:toAlpha="0"?/>
Activity類代碼如下:
public?class?ViewFlipperActivity extends?Activity implements?OnTouchListener {
private?ViewFlipper viewFlipper;
private?Animation translateIn;
private?Animation translateOut;
private?Animation alphaIn;
private?Animation alphaOut;
?
@Override
public?boolean?onTouch(View view, MotionEvent event) {
switch?(view.getId()) {
case?R.id.imageview1://觸摸第一個圖像時:移動補間動畫
viewFlipper.setInAnimation(translateIn);
viewFlipper.setOutAnimation(translateOut);
break;
case?R.id.imageview2://觸摸第二個圖像時:透明漸變補間動畫
viewFlipper.setInAnimation(alphaIn);
viewFlipper.setOutAnimation(alphaOut);
break;
}
?
viewFlipper.showNext();//顯示下一個View
?
return?false;
}
?
@Override
public?void?onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewFlipper?= (ViewFlipper) getLayoutInflater().inflate(R.layout.viewflipper, null);
View view1 = getLayoutInflater().inflate(R.layout.layout1, null);
View view2 = getLayoutInflater().inflate(R.layout.layout2, null);
View view3 = getLayoutInflater().inflate(R.layout.layout3, null);
viewFlipper.addView(view1);
viewFlipper.addView(view2);
viewFlipper.addView(view3);
setContentView(viewFlipper);
translateIn?= AnimationUtils.loadAnimation(this, R.anim.translatein);
translateOut?= AnimationUtils.loadAnimation(this, R.anim.translateout);
alphaIn?= AnimationUtils.loadAnimation(this, R.anim.alphain);
alphaOut?= AnimationUtils.loadAnimation(this, R.anim.alphaout);
ImageView imageView1 = (ImageView) view1.findViewById(R.id.imageview1);
ImageView imageView2 = (ImageView) view2.findViewById(R.id.imageview2);
imageView1.setOnTouchListener(this);
imageView2.setOnTouchListener(this);
?
}
}
其中布局文件viewflipper.xml的代碼如下:
<ViewFlipper?xmlns:android="http://schemas.android.com/apk/res/android"
????android:layout_width="fill_parent"
????android:layout_height="fill_parent"?>
</ViewFlipper>
運行本程序,觸摸第一幅圖像會以水平移動的方式切換到第二幅圖像,再次觸摸第二幅圖像會以淡入淡出的方式切換到第三幅圖像。具體程序運行效果請參看圖2.1.8和圖2.1.9。
?
?
?
?
任務實訓部分?
?
1:利用幀動畫技術開發一個游戲人物走動的小游戲
訓練技能點
幀動畫的實現原理及技巧
需求說明
在任何一款游戲中,都不可避免地出現人物等對象走動的情景,結合本章所學的知識,我們可以事先提供一系列的圖片,然后利用幀動畫的原理實現。
實現步驟
具體的實現步驟請參看課本2.2節中的內容。本案例的難點是準備合適的人物行走過程中的圖像,然后在動畫文件中進行合適的設置。
?
?
2:?模擬實現汽車由近到遠逐漸消失的場景
訓練技能點
??移動補間動畫
??縮放補間動畫
??透明補間動畫
需求說明
在我們的手機程序中會經常看到一個物體由遠到近或由近到遠、體積由大到小或由小到大、逐漸透明或逐漸消失的應用。比如極品飛車游戲中漸行漸遠的汽車。
本實訓中要求模擬實現汽車由近到遠逐漸消失的過程。汽車由近到遠可通過移動補間動畫實現;在消失過程中體積變小的過程可以通過縮放補間動畫實現;為了增加用戶的觀感,可以在汽車消失的過程中為汽車設置一個透明度逐漸變化的過程,這個可通過透明補間動畫實現。
?
鞏固練習
一、簡答題
1.?簡述實現幀動畫的基本步驟。
?
?
2.?簡要描述Android默認提供的四類補間動畫。
?
?
二、上機練習
完成一個蝴蝶振動翅膀飛動的效果,蝴蝶的振翅效果可通過逐幀動畫實現,飛行時位置的改變可通過補間動畫實現。
總結
以上是生活随笔為你收集整理的Android中的动画的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 十八 蓝牙及Wi-Fi
- 下一篇: Android期末考试题