簡介
Android動畫主要有三種類型:View動畫、幀動畫和屬性動畫。其中,幀動畫也是View動畫的一種,它通過順序播放一系列圖像而產生動畫效果,只不過它和一般的平移、旋轉等View動畫在表現形式上略有不同。而屬性動畫是API11的新特性,在Android 3.0以下版本的手機中無法使用。下面主要介紹View動畫。
View動畫是一種作用于View對象的動畫,它支持4種動畫效果,分別為平移(translate)、旋轉(rotate)、縮放(scale)和透明度(alpha)。這四種動畫分別對應于Android中的TranslateAnimation、RotateAnimation、ScaleAnimation和AlphaAnimation這四個類。這幾種動畫均可以通過XML格式定義或通過Java代碼動態創建。
實現原理
每次繪制視圖時,View所在的ViewGroup中的drawChild函數會獲取該view的Animation的Transformation值,然后調用canvas.concat(transformToApply.getMatrix())函數,通過內部的矩陣運算完成動畫幀。如果動畫沒有完成,就繼續調用invalidate()函數,啟動下次繪制來驅動動畫,從而完成整個動畫的繪制。由此可見,View動畫其實是一個矩陣運算的過程。
優缺點
優勢:使用簡單,兼容性好
缺陷:
- 不具備交互性,View動畫作用的實際上是View的影像,而非真正改變了View的屬性狀態。也就是說,View動畫結束后,即便使用setFillAfter(true)使得view保持在動畫結束時的位置,view的真實位置依舊未發生變化,仍然處于最開始定義時的位置。因此,當view動畫結束后,其響應位置仍然位于動畫開始前的位置,這就使得其不具備交互性;
- View動畫只能作用于View對象,且提供的動畫種類有限;
View動畫的使用
通過Java代碼動態創建動畫
步驟:
- 創建TranslateAnimation、RotateAnimation、ScaleAnimation或AlphaAnimation對象;
- 設置創建的動畫對象的屬性,如動畫執行時間、延遲時間、起始位置、結束位置等;
- 通過View.startAnimation()方法開啟動畫;
注:可以通過Animation.setAnimationListener()設置動畫的監聽器,監聽動畫的開始、結束和重復狀態,并在必要的時候添加自己的操作;
示例:
- 平移動畫:
TranslateAnimation translate = new TranslateAnimation(0, 120, 0, 100);
translate.setFillAfter(true);
translate.setDuration(1000);
image.startAnimation(translate);
- 旋轉動畫:
final RotateAnimation rotate1 = new RotateAnimation(0, 360); // 圍繞自己的左上角向右旋轉360度
final RotateAnimation rotate2 = new RotateAnimation(0, 90, Animation.RELATIVE_TO_PARENT, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f); // X軸坐標向右偏移0.5倍父控件寬度,Y軸坐標向下偏移0.5倍自身寬度,然后圍繞該點向右旋轉90度
rotate1.setDuration(1000); //設置動畫時長
// 設置動畫事件監聽器
rotate1.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(mContext, "Start rotate", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(mContext, "End rotate", Toast.LENGTH_SHORT).show();
rotate2.setDuration(1000);
image.startAnimation(rotate2);
}
@Override
public void onAnimationRepeat(Animation animation) {
Toast.makeText(mContext, "Repeat rotate", Toast.LENGTH_SHORT).show();
}});
image.startAnimation(mAnimation); // 開始動畫
+ 縮放動畫:
```Java
ScaleAnimation scale = new ScaleAnimation(1, 1.5f, 1, 1.5f, Animation.RELATIVE_TO_PARENT, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
scale.setFillAfter(true);
scale.setDuration(1000);
image.startAnimation(scale);
- 透明度動畫:
AlphaAnimation alpha = new AlphaAnimation(1, 0);
alpha.setDuration(1000);
alpha.setRepeatMode(Animation.REVERSE); //設置重復模式
alpha.setRepeatCount(5); //設置重復次數
image.startAnimation(alpha);
+ 動畫集:
```Java
AnimationSet as = new AnimationSet(true); // 動畫集共享插值器
as.setDuration(3000);AlphaAnimation aa = new AlphaAnimation(0. 1);
aa.setDuration(1000);
as.addAnimation(aa);
TranslateAnimation ta = new TranslateAnimation(0, 100, 0, 100);
ta.setDuration(1000);
as.addAnimation(ta);
image.startAnimation(as);
屬性解析:
- 動畫的原點默認為控件自身的左上角,向右為X軸正向,向下為Y軸正向
- 動畫常見共有屬性:
- setInterpolator(Interpolator i):設置動畫插值器(后面解釋),即設置動畫的加速模式,默認為線性插值器(勻速變化),還可以設置為AccelerateDecelerateInterpolator、AccelerateInterpolator等,或者自定義
- setFillAfter(boolean fillAfter): 動畫結束后是否保持在結束狀態,true表示保持在結束時的狀態,false表示返回開始前的狀態
- setFillBefore(boolean fillBefore):true表示動畫結束時,畫面停留在第一幀
- setDuration(long durationMillis):動畫持續時長,單位:毫秒
- setRepeatCount(int repeatCount):動畫重復次數,-1表示無限循環
- setRepeatMode(int repeatMode):動畫重復模式,為RESTART或REVERSE
- setStartTime(long startTimeMillis):動畫開始時間,以毫秒表示
- setStartOffset(long startOffset):動畫延遲時長,即延遲startOffset毫秒開始動畫,當startOffset>0時,動畫開始時間為startTimeMillis+startOffset
- setZAdjustment(int zAdjustment):動畫過程中Z軸方向的模式,默認為normal
- 平移動畫屬性:
public TranslateAnimation(Context context, AttributeSet attrs);
public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta,
float toYDelta);
public TranslateAnimation(int fromXType, float fromXValue, int toXType,
float toXValue, int fromYType, float fromYValue, int toYType, float toYValue);
如上為TranslateAnimation的三個構造方法,最終均為了設置第三個構造方法中的幾個參數所對應的TranslateAnimation屬性值,所以下面分別介紹這些屬性的含義。
fromXType 和 fromXValue:這倆屬性分別表示平移起點X軸方向的偏移類型和偏移量,fromXType有三種取值可選,分別為Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF 和 Animation.RELATIVE_TO_PARENT;
fromXType取值為Animation.ABSOLUTE時,表示X軸方向的平移起點絕對平移fromXValue個像素點,此時fromXValue為一個絕對像素值;
fromXType取值為Animation.RELATIVE_TO_SELF時,表示X軸方向的平移起點相對自身平移fromXValue **** 控件寬度個像素點,此時fromXValue為一個百分比值,表示偏移量相對控件自身寬度的百分比;
fromXType取值為Animation.RELATIVE_TO_PARENT 時,表示X軸方向的平移起點相對父控件平移fromXValue **** 父控件寬度個像素點,此時fromXValue為一個百分比值,表示偏移量相對父控件寬度的百分比;fromYType 和 fromYValue:分別表示平移起點Y軸方向的偏移類型和偏移量,具體含義同fromXType 和 fromXValue;
toXType 和 toXValue、toYType 和 toYValue:則表示終點位置的偏移量,具體含義同起點偏移量;
旋轉動畫屬性:
public RotateAnimation(Context context, AttributeSet attrs)
public RotateAnimation(float fromDegrees, float toDegrees)
public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
int pivotYType, float pivotYValue)
如上為RotateAnimation的四個構造方法,其目的均為了設置fromDegrees、toDegrees、pivotXType、pivotXValue、pivotYType、pivotYValue這幾個屬性值,下面對這幾個屬性分別進行介紹。
fromDegrees 和 toDegrees:這兩個屬性分別表示旋轉起始角度和終止角度;
-
pivotXType、pivotXValue、pivotYType、pivotYValue:這四個屬性用于設置旋轉中心點位置。
pivotXType 和 pivotXValue分別表示旋轉中心在X軸方向相對原點(即控件左上角)的偏移類型和偏移量,pivotXType有三個可選取值:Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF 和 Animation.RELATIVE_TO_PARENT,分別表示絕對偏移、相對自身偏移和相對父控件偏移,當取Animation.ABSOLUTE時,pivotXValue是一個絕對數值,否則pivotXValue是一個相對數值(取值為1表示100%)。
pivotYType 和 pivotYValue:分別表示旋轉中心在Y軸方向相對原點的偏移類型和偏移量,具體含義同pivotXType 和 pivotXValue。示例使用如下:
final RotateAnimation rotate2 = new RotateAnimation(0, 90, Animation.RELATIVE_TO_PARENT, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
// X軸坐標向右偏移0.5倍父控件寬度,Y軸坐標向下偏移0.5倍自身寬度,然后圍繞該點向右旋轉90度
- 縮放動畫屬性:
public ScaleAnimation(Context context, AttributeSet attrs)
public ScaleAnimation(float fromX, float toX, float fromY, float toY)
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)
如上為ScaleAnimation的四個構造函數,最終均為了設置ScaleAnimation的如下幾個屬性:
fromX、toX、fromY、 toY、pivotXType、pivotXValue、pivotYType 和 pivotYValue。
fromX 和 toX:這兩個屬性分別表示水平方向上相對自身的起始縮放因子和終止縮放因子,1表示100%,即原始大小,因此水平方向縮放的總長度為(toX-fromX) * width
fromY 和 toY:這兩個屬性分別表示垂直方向上相對自身的起始縮放因子和終止縮放因子
-
pivotXType、pivotXValue、pivotYType 和 pivotYValue:這四個屬性用于控制縮放中心坐標點位置。具體含義參見旋轉動畫屬性說明部分。
示例使用如下:
ScaleAnimation scale = new ScaleAnimation(1, 1.5f, 1, 1.5f, Animation.RELATIVE_TO_PARENT, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
// 表示以X坐標向右偏移0.5倍父控件寬度,Y坐標向下偏移0.5倍自身高度的點為縮放中心點
// 將控件的水平和垂直方向分別從當前寬高放大0.5倍
```
- 透明度動畫屬性:
public AlphaAnimation(Context context, AttributeSet attrs)
public AlphaAnimation(float fromAlpha, float toAlpha)
如上為AlphaAnimation的兩個構造方法,主要看第二個構造方法中的兩個屬性fromAlpha 和 toAlpha,這兩個屬性分別表示動畫開始時的透明度和結束時的透明度,0.0表示完全透明,即不可見,1.0表示完全不透明。
示例使用如下:
AlphaAnimation alpha = new AlphaAnimation(1, 0);
// 表示將控件從不透明狀態調整到完全透明狀態
- 動畫集(AnimationSet)屬性:
動畫集用于將一組一起播放的動畫組合為一個動畫。動畫集從父類Animation中繼承的一些屬性的作用方式需要認真加以理解,因為不同屬性的表現方式各異,有些屬性只作用于動畫集自身,有些屬性會作用于動畫集中的子動畫,而有些屬性又會被忽略。- duration, repeatMode, fillBefore, fillAfter: 當為AnimationSet設置了這幾個屬性的時候,這幾個屬性將會作用于該動畫集中的所有子動畫中
- repeatCount, fillEnabled: 這兩個屬性在AnimationSet中不起作用,將會被忽略;
- startOffset, shareInterpolator: 這兩個屬性將作用于AnimationSet自身