Android動畫系列(一)
動畫是Android一個相當重要的組成部分,作為安卓開發者也許多多少少用過一些動畫三方庫。我一直想要系統的整理一下動畫相關的知識。在網上逛了逛,發現很多都已經總結過了,啟航的自定義控制元件三部曲是他花費大心思寫的。真心很不錯,鴻洋也寫過類似動畫的文章,郭神也發過動畫介紹,這裡我就從頭開始,參考著他們的和官方文章學習,這裡我只是做一下學習筆記。谷歌官方動畫文件:https://developer.android.com/guide/topics/resources/animation-resource.html
動畫基本介紹
安卓提供的動畫主要分為兩種:Property Animation和View Animation。而View Animation又分為TweenAnimation和FrameAnimation。這些都是安卓提供的原生動畫類。那麼接下來挨著學習,怎麼使用。
Animation
Animation共有屬性,介紹一下經常用的。Animation類是所有動畫(scale、alpha、translate、rotate)的基類。
android:duration 動畫持續時間,以毫秒為單位
android:fillAfter 如果設定為true,控制元件動畫結束時,將保持動畫最後時的狀態
android:repeatCount 重複次數
android:repeatMode 重複型別,有reverse和restart兩個值,reverse表示倒序回放,restart表示重新放一遍,必須與repeatCount一起使用才能看到效果。因為這裡的意義是重複的型別,即回放時的動作。
android:interpolator 設定插值器,其實就是指定的動作效果,比如彈跳效果等,不在這小節中講解,後面會單獨列出一單講解。
View Animation
這裡包含了TweenAnimation(補間動畫)和FrameAnimation(逐幀動畫)。可以使用xml編寫,也可以使用類來編寫。
Tween Animation
TweenAnimation包含了scale(縮放),translate(平移),alpha(漸變),rotate(旋轉)四種動畫效果,使用xml設定動畫的時候,需要在res目錄下建立一個anim資料夾,建立資原始檔就行了。類似這樣res/anim/filename.xml。這裡必須建立anim資料夾用於存放動畫資原始檔。因為會通過這個檔名作為使用的ID。R.anim.filename。使用xml的時候通過AnimationUtil的loadAnimation匯入xml,然後呼叫目標控制元件的startAnimation(animation)開啟動畫。
Scale
scale標籤是縮放動畫,可以實現動態調控制元件尺寸的效果,有下面幾個屬性:
android:fromXScale 起始的X方向上相對自身的縮放比例,浮點值,比如1.0代表自身無變化,0.5代表起始時縮小一倍,2.0代表放大一倍;
android:toXScale 結尾的X方向上相對自身的縮放比例,浮點值;
android:fromYScale 起始的Y方向上相對自身的縮放比例,浮點值,
android:toYScale 結尾的Y方向上相對自身的縮放比例,浮點值;
android:pivotX 縮放起點X軸座標,可以是數值、百分數、百分數p 三種樣式,比如 50、50%、50%p,當為數值時,表示在當前View的左上角,即原點處加上50px,做為起始縮放點;如果是50%,表示在當前控制元件的左上角加上自己寬度的50%做為起始點;如果是50%p,那麼就是表示在當前的左上角加上父控制元件寬度的50%做為起始點x軸座標。(具體意義,後面會舉例演示)
android:pivotY 縮放起點Y軸座標,取值及意義跟android:pivotX一樣。
set標籤,包含 alpha, scale, translate, rotate, 或者 set。擁有它自己的屬性,android:interpolator 插值器,有很多預設選擇,之後會詳細介紹插值器。android:shareInterpolator 布林值,如果設定為true,那麼它的子動畫會受到該插值器的影響。
接下來例項:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="0.0"
android:toXScale="1.5"
android:fromYScale="0.0"
android:toYScale="1.5"
android:pivotX="50"
android:pivotY="50"
android:duration="700"
>
</scale>
</set>
在標籤屬性android:pivotX中有三種取值,數,百分數,百分數p;體現在建構函式中,就是最後一個建構函式的pivotXType,它的取值有三個,Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF和Animation.RELATIVE_TO_PARENT;
ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f,1.5f,0.0f,1.5f,Animation.ABSOLUTE,50f,Animation.ABSOLUTE,50f);
將android:pivotX=”50” android:pivotY=”50”修改為android:pivotX=”50%” android:pivotY=”50%”。就是從控制元件中心開始動畫。
ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f,1.5f,0.0f,1.5f,Animation.RELATIVE_TO_SELF,50f,Animation.RELATIVE_TO_SELF,50f);
將android:pivotX=”50%” android:pivotY=”50%”
修改為android:pivotX=”50%p” android:pivotY=”50%p”。就是基於父控制元件的百分比。
ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f,1.5f,0.0f,1.5f,Animation.RELATIVE_TO_PARENT,50f,Animation.RELATIVE_TO_PARENT,50f);
設定重複次數,和重複的模式。
scaleAnimation.setRepeatCount(1);
scaleAnimation.setRepeatMode(Animation.RESTART|Animation.REVERSE);
android:repeatCount=”1”, android:repeatMode=”reverse|restart”
android:repeatMode=”reverse” android:repeatMode=”restart”
Translate
平移動畫。xml屬性:
android:fromXDelta 起始點X軸座標,可以是數值、百分數、百分數p 三種樣式,比如 50、50%、50%p,具體意義已在scale標籤中講述,這裡就不再重講
android:fromYDelta 起始點Y軸從標,可以是數值、百分數、百分數p 三種樣式;
android:toXDelta 結束點X軸座標
android:toYDelta 結束點Y軸座標
例項:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="100%"
android:toYDelta="100%"
android:duration="800"
>
</translate>
</set>
java程式碼:
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.ABSOLUTE,0.0f,Animation.ABSOLUTE,100f,Animation.ABSOLUTE,0.0f,Animation.ABSOLUTE,100f);
ROTATE
旋轉動畫,屬性:
android:fromDegrees 開始旋轉的角度位置,正值代表順時針方向度數,負值程式碼逆時針方向度數
android:toDegrees 結束時旋轉到的角度位置,正值代表順時針方向度數,負值程式碼逆時針方向度數
android:pivotX 縮放起點X軸座標,可以是數值、百分數、百分數p 三種樣式,比如 50、50%、50%p,具體意義已在scale標籤中講述,這裡就不再重講
android:pivotY 縮放起點Y軸座標,可以是數值、百分數、百分數p 三種樣式,比如 50、50%、50%p
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="800">
</rotate>
</set>
RotateAnimation rotateAnimation = new RotateAnimation(0f,360f,Animation.RELATIVE_TO_SELF,50f,Animation.RELATIVE_TO_SELF,50f);
android:toDegrees=”360” android:toDegrees=”-360”
ALPHA
漸變動畫,屬性:
android:fromAlpha 動畫開始的透明度,從0.0 –1.0 ,0.0表示全透明,1.0表示完全不透明
android:toAlpha 動畫結束時的透明度,也是從0.0 –1.0 ,0.0表示全透明,1.0表示完全不透明
<?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="800">
</alpha>
</set>
AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f,1.0f);
alphaAnimation.setDuration(800);
SET
動畫集合,多個動畫效果觸發。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0"
android:toAlpha="1.0"
android:duration="2000">
</alpha>
<rotate
android:fromDegrees="0"
android:toDegrees="720"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000">
</rotate>
<scale
android:fromXScale="0.0"
android:toXScale="1.5"
android:fromYScale="0.0"
android:toYScale="1.5"
android:pivotY="50%"
android:pivotX="50%"
android:duration="2000">
</scale>
</set>
對應java程式碼:
AnimationSet animationSet = new AnimationSet(false);
AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f,1.0f);
alphaAnimation.setDuration(2000);
RotateAnimation rotateAnimation = new RotateAnimation(0.0f,720f,Animation.RELATIVE_TO_SELF,50f,Animation.RELATIVE_TO_SELF,50f);
rotateAnimation.setDuration(2000);
ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f,1.5f,0.0f,1.5f,Animation.RELATIVE_TO_SELF,50f,Animation.RELATIVE_TO_SELF,50f);
scaleAnimation.setDuration(2000);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(scaleAnimation);
FrameAnimation
frameAnimation就是逐幀動畫,一張一張的播放。就像flash幀動畫一樣,設定每幀播放時間,連續播放就成了動畫。
存放位置:res/drawable/filename.xml 也就是需要在res檔案下有個drawable資料夾,在那裡建立frameAnimation的檔案。呼叫時:R.drawable.filename
基本標籤:
animation-list 必須存在並且必須要作為根元素,可以包含一或多個item元素。它有自己的屬性 android:oneshot 如果定義為true的話,此動畫只會執行一次,如果為false則一直迴圈。
item 作為每一幀動畫的圖片資源。它有自己的屬性,android:drawable,設定圖片drawable資源。android:duration 整數型,毫秒值。設定每幀播放的動畫。
那麼看看例項:
xml程式碼:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/img1" android:duration="500"></item>
<item android:drawable="@drawable/img2" android:duration="500"></item>
<item android:drawable="@drawable/img1" android:duration="500"></item>
<item android:drawable="@drawable/img2" android:duration="500"></item>
</animation-list>
在Activity中具體使用方式。
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
rocketAnimation.start();
如果想要使用純java程式碼實現,而不使用xml設定。
AnimationDrawable drawable = new AnimationDrawable();
for (int i = 1; i < 3; i++) {
String path = "img"+i;
int id = getResources().getIdentifier(path,"drawable",getPackageName());
Drawable drawable1 = getResources().getDrawable(id);
drawable.addFrame(drawable1,500);
}
drawable.setOneShot(false);
image.setBackgroundDrawable(drawable);
drawable.start();
這裡有個小技巧,就是將字串的命名id轉換為int資源id。
int id = getResources().getIdentifier(path,"drawable",getPackageName());
好了,基礎動畫的使用也就這麼多了。我這個學習筆記很多事參考官網的文件和啟航的基礎動畫講解。