Android動畫解析(一)-----逐幀動畫和補間動畫
阿新 • • 發佈:2019-01-25
今天專案又用到了動畫,發現之前掌握的那些又遺忘了不少,趁著有時間,再重新捋順一邊。
Android中的動畫分為 逐幀動畫,補間動畫,屬性動畫 三種.
逐幀動畫(Frame Animation)
逐幀動畫:就像GIF圖片一樣,通過一系列的Drawable依次顯示來模擬動畫效果。
- 使用方式:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="@drawable/pic1" android:duration="150" />
<item android:drawable="@drawable/pic2" android:duration="150" />
<item android:drawable="@drawable/pic3" android:duration="150" />
</animation-list>
<!--XML檔案以<animation-list>為根元素,
以<item>表示要輪換顯示的圖片,
oneshot屬性,用於設定播放模式(是單次播放還是迴圈播放)
duration屬性表示各項顯示的時間。
XML檔案要放在/res/drawable/目錄下-->
- 呼叫方法:
AnimationDrawable animationDrawable = (AnimationDrawable) loadingImage.getDrawable();
animationDrawable.start();//開始動畫
animationDrawable.stop();//結束動畫
補間動畫(Tween Animation)
補間動畫:給出兩個關鍵幀,通過一些演算法將給定屬性值在給定的時間內在兩個關鍵幀間漸變。
補間動畫是使用Animation類建立的,下面的列表說明了四種可用的動畫型別:
動畫型別 | 簡介 |
---|---|
AlphaAnimation | 可以改變View的透明度。(透明度漸變動畫) |
ScaleAnimation | 允許縮放選中的View。(縮放動畫) |
RotateAnimation | 可以在XY平面上旋轉選中的View。(旋轉動畫) |
TranslateAnimation | 可以在螢幕上移動選中的View。(平移動畫) |
當View設定補件動畫後,動畫只是移動了內容,View本身其實還在原地,所以點選事件也還是在原地,如果想讓點選事件跟著移動,最簡單的是使用屬性動畫。
TranslateAnimation(平移動畫)
java程式碼寫法
TranslateAnimation
animation = new TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta);
// fromXDelta 屬性為動畫起始時 X座標上的位置 toXDelta 屬性為動畫結束時 X座標上的位置
// fromYDelta 屬性為動畫起始時 Y座標上的位置 toYDelta 屬性為動畫結束時 Y座標上的位置
// 沒有指定fromXType toXType fromYType toYType 時候, 預設是以自己為相對參照物
...
View.startAnimation(animation);
XML檔案寫法
通過配置XML檔案來實現平移動畫,檔案需要放在res\anim目錄中,在動畫檔案中通過<translate>
標籤設定移動效果。首先在res\anim目錄下建一個動畫檔案
translate_tween.xml,該檔案的內容如下:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXDelta="0"
android:fromYDelta="0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toXDelta="60"
android:toYDelta="60" >
</translate>
<!-- android:interpolator 動畫差值器-->
<!-- android:duration 動畫持續時間,以毫秒為單位 -->
<!-- android:fillAfter 如果設定為true,控制元件動畫結束時,將保持動畫最後時的狀態-->
<!-- android:fillBefore 如果設定為true,控制元件動畫結束時,還原到開始動畫前的狀態-->
<!-- android:fillEnabled 與android:fillBefore 效果相同,都是在動畫結束時,將控制元件還原到初始化狀態-->
<!-- android:repeatCount 重複次數-->
<!-- android:repeatMode 重複型別,有reverse和restart兩個值,reverse表示倒序回放,restart表示重新放一遍,必須與repeatCount一起使用才能看到效果。因為這裡的意義是重複的型別,即回放時的動作。-->
// 在程式碼中這樣呼叫
Animation animation=AnimationUtils.loadAnimation(this, R.anim.translate_tween);
View.startAnimation(animation);
或者用這種方式
//View.setAnimation(animation);
//animation.start();
TranslateAnimation特有屬性
* android:fromXDelta="0%" 動畫開始執行時X軸方向控制元件的起始位置,
* 當value加%時(例如80%),意思是相對於控制元件的原始位置往右的80%控件寬度的位置
* 又例如value為-20%時,意思是相對於控制元件的原始位置往左的20%控件寬度的位置。
* 當Value不加%時(例如80),表示相對於控制元件的原始位置往右80個畫素(px)的位置,
* 又如當Value為-20時,即往左20個畫素。
* android:toXDelta="100%"動畫結束執行時X軸方向控制元件的結束位置,Value可以加%,也可以不加%,原理同上
* android:fromYDelta="0%"動畫開始執行時Y軸方向控制元件的起始位置,Value可以加%,也可以不加%,原理同上
* android:toYDelta="100%"動畫結束執行時Y軸方向控制元件的結束位置,Value可以加%,也可以不加%,原理同上
AlphaAnimation(透明度漸變動畫)
Java程式碼寫法
AlphaAnimation mAlphaAnimation = new AlphaAnimation(float fromAlpha, float toAlpha);
//fromAlpha:設定動畫開始時控制元件的透明度
//toAlpha:設定動畫結束時的控制元件的透明度
//兩個值取值都為0~1之間,0.0為透明,控制元件不顯示,1.0為不透明,控制元件全部顯示
...
View.startAnimation(mAlphaAnimation);
XML寫法
同樣檔案需要放在res\anim目錄中,在動畫檔案中通過<alpha>
標籤設定漸變效果。首先在res\anim目錄下建一個動畫檔案
alpha_tween.xml,該檔案的內容如下:
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha= "0.0"
android:toAlpha= "1.0"
>
</alpha>
<!-- android:interpolator 動畫差值器-->
<!-- android:duration 動畫持續時間,以毫秒為單位 -->
<!-- android:fillAfter 如果設定為true,控制元件動畫結束時,將保持動畫最後時的狀態-->
<!-- android:fillBefore 如果設定為true,控制元件動畫結束時,還原到開始動畫前的狀態-->
<!-- android:fillEnabled 與android:fillBefore 效果相同,都是在動畫結束時,將控制元件還原到初始化狀態-->
<!-- android:repeatCount 重複次數-->
<!-- android:repeatMode 重複型別,有reverse和restart兩個值,reverse表示倒序回放,restart表示重新放一遍,必須與repeatCount一起使用才能看到效果。因為這裡的意義是重複的型別,即回放時的動作。-->
// 在程式碼中這樣呼叫
Animation animation=AnimationUtils.loadAnimation(this, R.anim.alpha_tween);
View.startAnimation(animation);
或者用這種方式
//View.setAnimation(animation);
//animation.start();
AlphaAnimation特有屬性
android:fromAlpha:動畫開始時的透明度,變化範圍為0.0-1.0,0.0表示完全透明,1.0表示完全不透明
android:toAlpha:動畫結束是的透明度,變化範圍和意義同上。
RotateAnimation(旋轉動畫)
Java程式碼寫法
RotateAnimation mRotateAnimation = new RotateAnimation(float fromDegrees, float toDegrees,
int pivotXType, float pivotXValue, int pivotYType, float pivotYValue);
// android:fromDegrees :動畫開始時旋轉的角度位置,float型別,正值代表順時針方向度數,負值程式碼逆時針方向度數
//android:toDegrees : 動畫結束時旋轉到的角度位置,float型別,正值代表順時針方向度數,負值程式碼逆時針方向度數
//android:pivotXType: 確定動畫在X軸的中心位置型別。與下面的pivotXValue結合,確定X軸上旋轉中心。(取值見下表)
//android:pivotXValue :旋轉點X軸座標值,float型別,可以是數值、百分數、百分數p三種樣式,比如50、50%、50%p
//當為數值時,表示在當前View的左上角,即原點處加上50px,做為旋轉點X座標,
//如果是50%;表示在當前控制元件的左上角加上自己寬度的50%做為旋轉點X座標;
//如果是50%p,那麼就是表示在當前控制元件的左上角加上父控制元件寬度的50%做為旋轉點X座標。
//android:pivotYType: 確定動畫在Y軸的中心位置型別。取值及意義跟android:pivotXType一樣。
//android:pivotYValue:旋轉點Y軸座標值,取值及意義跟android:pivotX一樣。
...
View.startAnimation(mRotateAnimation);
pivotXType值 | 效果 |
---|---|
Animation.ABSOLUTE | 預設值,圍繞設定動畫控制元件的左上角旋轉與pivotXValue = 0,pivotYVaule = 0效果相同 |
Animation.RELATIVE_TO_PARENT | 設定動畫控制元件的左上角為座標原點(0,0),動畫旋轉軸的座標為(parent.getWidth*pivotXValue,parent.getHeight*pivotYValue)[parent為view的父控制元件]負數向左(X軸)/上(Y軸)偏移,正數向右(X軸)/下(Y軸)偏移; |
Animation.RELATIVE_TO_SELF | 設定動畫控制元件的左上角為座標原點(0,0),動畫旋轉軸的座標為(view.getWidth*pivotXValue,view.getHeight*pivotYValue)負數向左(X軸)/上(Y軸)偏移,正數向右(X軸)/下(Y軸)偏移; |
XML檔案寫法
在res\anim目錄下建一個動畫檔案rotate_tween.xml,該檔案的內容如下:
<?xml version="1.0" encoding= "utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees= "0"
android:toDegrees= "360"
android:pivotX= "50%"
android:pivotY= "50%"
>
</rotate>
<!-- android:interpolator= 動畫差值器-->
<!-- android:duration 動畫持續時間,以毫秒為單位 -->
<!-- android:fillAfter 如果設定為true,控制元件動畫結束時,將保持動畫最後時的狀態-->
<!-- android:fillBefore 如果設定為true,控制元件動畫結束時,還原到開始動畫前的狀態-->
<!-- android:fillEnabled 與android:fillBefore 效果相同,都是在動畫結束時,將控制元件還原到初始化狀態-->
<!-- android:repeatCount 重複次數-->
<!-- android:repeatMode 重複型別,有reverse和restart兩個值,reverse表示倒序回放,restart表示重新放一遍,必須與repeatCount一起使用才能看到效果。因為這裡的意義是重複的型別,即回放時的動作。-->
// 在程式碼中這樣呼叫
Animation animation=AnimationUtils.loadAnimation(this, R.anim.rotate_tween);
View.startAnimation(animation);
或者用這種方式
//View.setAnimation(animation);
//animation.start();
RotateAnimation特有屬性
android:fromDegrees:動畫開始時旋轉的角度位置,float型別,正值代表順時針方向度數,負值程式碼逆時針方向度數
android:toDegrees: 動畫結束時旋轉到的角度位置,float型別,正值代表順時針方向度數,負值程式碼逆時針方向度數
android:pivotX:旋轉點X軸座標,float型別,可以是數值、百分數、百分數p三種樣式,比如50、50%、50%p,當為數值時,表示在當前View的左上角,即原點處加上50px,做為旋轉點X座標,如果是50%;表示在當前控制元件的左上角加上自己寬度的50%做為旋轉點X座標;如果是50%p,那麼就是表示在當前控制元件的左上角加上父控制元件寬度的50%做為旋轉點X座標。
android:pivotY:旋轉點Y軸座標,取值及意義跟android:pivotX一樣。
ScaleAnimation(縮放動畫)
Java程式碼寫法
ScaleAnimation mScaleAnimation = ScaleAnimation(float fromX, float toX, float fromY,
float toY,int pivotXType, float pivotXValue, int pivotYType, float pivotYValue);
// float fromX 動畫起始時 X座標上的伸縮尺寸 比如1.0代表自身無變化,0.5代表起始時縮小一倍,2.0代表放大一倍
// float toX 動畫結束時 X座標上的伸縮尺寸
// float fromY 動畫起始時Y座標上的伸縮尺寸
// float toY 動畫結束時Y座標上的伸縮尺寸
//android:pivotXType: 確定動畫在X軸的中心位置型別。與下面的pivotXValue結合,確定X軸上縮放中心點。。(取值見下表)
// float pivotXValue 動畫相對於物件的X座標的開始位置
// int pivotYType 動畫在Y軸相對於物件位置型別
// float pivotYValue 動畫相對於物件的Y座標的開始位置
...
View.startAnimation(mScaleAnimation);
pivotXType值 | 效果 |
---|---|
Animation.ABSOLUTE | 預設值,設定動畫控制元件從左上角縮放,與pivotXValue = 0,pivotYVaule = 0效果相同 |
Animation.RELATIVE_TO_PARENT | 設定動畫控制元件的左上角為座標原點(0,0),動畫縮放點的座標為(parent.getWidth*pivotXValue,parent.getHeight*pivotYValue)【parent為view的父控制元件】負數向左(X軸)/上(Y軸)偏移,正數向右(X軸)/下(Y軸)偏移; |
Animation.RELATIVE_TO_SELF | 設定動畫控制元件的左上角為座標原點(0,0),動畫所放點的座標為(view.getWidth*pivotXValue,view.getHeight*pivotYValue)負數向左(X軸)/上(Y軸)偏移,正數向右(X軸)/下(Y軸)偏移; |
XML檔案寫法
<?xml version="1.0" encoding= "utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale= "2.0"
android:toXScale= "1.0"
android:fromYScale= "2.0"
android:toYScale= "1.0"
android:pivotX= "50%"
android:pivotY= "50%"
>
</scale>
<!-- android:interpolator= 動畫差值器-->
<!-- android:duration 動畫持續時間,以毫秒為單位 -->
<!-- android:fillAfter 如果設定為true,控制元件動畫結束時,將保持動畫最後時的狀態-->
<!-- android:fillBefore 如果設定為true,控制元件動畫結束時,還原到開始動畫前的狀態-->
<!-- android:fillEnabled 與android:fillBefore 效果相同,都是在動畫結束時,將控制元件還原到初始化狀態-->
<!-- android:repeatCount 重複次數-->
<!-- android:repeatMode 重複型別,有reverse和restart兩個值,reverse表示倒序回放,restart表示重新放一遍,必須與repeatCount一起使用才能看到效果。因為這裡的意義是重複的型別,即回放時的動作。-->
// 在程式碼中這樣呼叫
Animation animation=AnimationUtils.loadAnimation(this, R.anim.rotate_tween);
View.startAnimation(animation);
或者用這種方式
//View.setAnimation(animation);
//animation.start();
ScaleAnimation特有屬性
android:fromXScale起始的X方向上相對自身的縮放比例,型別float,比如1.0代表自身無變化,0.5代表起始時縮小一倍,2.0代表放大一倍
android:toXScale:結尾的X方向上相對自身的縮放比例,型別float
android:fromYScale:起始的Y方向上相對自身的縮放比例,型別float
android:toYScale:結尾的Y方向上相對自身的縮放比例,型別float
android:pivotX: 縮放起點X軸座標,可以是數值、百分數、百分數p ,具體意義roate中已經演示
android:pivotY:縮放起點Y軸座標,取值及意義與pivotX一樣
補間動畫設定動畫監聽事件
mAnimation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
//在動畫開始時執行處理
}
@Override
public void onAnimationRepeat(Animation animation) {
//在動畫重複時執行處理
}
@Override
public void onAnimationEnd(Animation animation) {
//在動畫完成後執行處理
}
});
AnimationSet
AnimationSet 可以讓許多個動畫在同一時間開始(也就是動畫的疊加)
注意 : AnimationSet 和 AnimatorSet 注意區分區別,這裡只做AnimationSet講解。下篇部落格講解AnimatorSet
Java 程式碼寫法
//建立動畫,引數表示他的子動畫是否共用一個插值器
AnimationSet animationSet = new AnimationSet(true);
//新增動畫(可以新增多個,每個動畫都可以單獨設定屬性)
animationSet.addAnimation(new AlphaAnimation(1.0f, 0.0f));
animationSet.addAnimation(new TranslateAnimation(0,120 , 0, -300));
//設定插值器
animationSet.setInterpolator(new LinearInterpolator());
//設定動畫持續時長
animationSet.setDuration(3000);
//設定動畫結束之後是否保持動畫的目標狀態
animationSet.setFillAfter(true);
//設定動畫結束之後是否保持動畫開始時的狀態
animationSet.setFillBefore(false);
//設定重複模式
animationSet.setRepeatMode(Animation.REVERSE);
//設定重複次數
animationSet.setRepeatCount(Animation.INFINITE);
//設定動畫延時時間
animationSet.setStartOffset(2000);
//取消動畫
animationSet.cancel();
//釋放資源
animationSet.reset();
//開始動畫
mIvImg.startAnimation(animationSet);
XML檔案寫法
檔案目錄:res/anim/animation_set.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:shareInterpolator="true">
<alpha
android:duration="2000"
android:fillAfter="true"
android:fillBefore="false"
android:fromAlpha="1.0"
android:repeatCount="-1"
android:repeatMode="reverse"
android:toAlpha="0.0"/>
<rotate
android:duration="2000"
android:fillAfter="true"
android:fillBefore="false"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="-1"
android:repeatMode="reverse"
android:toDegrees="360"/>
<set
android:interpolator="@android:anim/bounce_interpolator"
android:shareInterpolator="true"
android:startOffset="1000">
<scale
android:duration="2000"
android:fillAfter="true"
android:fillBefore="false"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="-1"
android:repeatMode="reverse"
android:toXScale="2.0"
android:toYScale="2.0"/>
<translate
android:duration="2000"
android:fillAfter="true"
android:fillBefore="false"
android:fromXDelta="0"
android:fromYDelta="0"
android:repeatCount="-1"
android:repeatMode="reverse"
android:toXDelta="200%"
android:toYDelta="200%"/>
</set>
</set>
Java程式碼中呼叫
AnimationSet animationSet = (AnimationSet)
AnimationUtils.loadAnimation(XmlViewAnimationActivity.this, R.anim.animation_set);
View.startAnimation(animationSet);
差值器效果
AccelerateDecelerateInterpolator============動畫開始與結束的地方速率改變比較慢,在中間的時候加速。
AccelerateInterpolator===================動畫開始的地方速率改變比較慢,然後開始加速。
AnticipateInterpolator ==================開始的時候向後然後向前甩。
AnticipateOvershootInterpolator=============開始的時候向後然後向前甩一定值後返回最後的值。
BounceInterpolator=====================動畫結束的時候彈起。
CycleInterpolator======================動畫迴圈播放特定的次數,速率改變沿著正弦曲線。
DecelerateInterpolator===================在動畫開始的地方快然後慢。
LinearInterpolator======================以常量速率改變。
OvershootInterpolator====================向前甩一定值後再回到原來位置。
PathInterpolator========================新增的,就是可以定義路徑座標,然後可以按照路徑座標來跑動;注意其座標並不是 XY,
而是單方向,也就是我可以從0~1,然後彈回0.5 然後又彈到0.7 有到0.3,直到最後時間結束。