簡介
Android動(dòng)畫主要有三種類型:View動(dòng)畫档礁、幀動(dòng)畫和屬性動(dòng)畫惠勒。其中赚抡,幀動(dòng)畫也是View動(dòng)畫的一種,它通過順序播放一系列圖像而產(chǎn)生動(dòng)畫效果纠屋,只不過它和一般的平移涂臣、旋轉(zhuǎn)等View動(dòng)畫在表現(xiàn)形式上略有不同。而屬性動(dòng)畫是API11的新特性售担,在Android 3.0以下版本的手機(jī)中無法使用赁遗。下面主要介紹View動(dòng)畫。
View動(dòng)畫是一種作用于View對象的動(dòng)畫族铆,它支持4種動(dòng)畫效果吼和,分別為平移(translate)、旋轉(zhuǎn)(rotate)骑素、縮放(scale)和透明度(alpha)炫乓。這四種動(dòng)畫分別對應(yīng)于Android中的TranslateAnimation、RotateAnimation献丑、ScaleAnimation和AlphaAnimation這四個(gè)類末捣。這幾種動(dòng)畫均可以通過XML格式定義或通過Java代碼動(dòng)態(tài)創(chuàng)建。
實(shí)現(xiàn)原理
每次繪制視圖時(shí)创橄,View所在的ViewGroup中的drawChild函數(shù)會(huì)獲取該view的Animation的Transformation值箩做,然后調(diào)用canvas.concat(transformToApply.getMatrix())函數(shù),通過內(nèi)部的矩陣運(yùn)算完成動(dòng)畫幀妥畏。如果動(dòng)畫沒有完成邦邦,就繼續(xù)調(diào)用invalidate()函數(shù),啟動(dòng)下次繪制來驅(qū)動(dòng)動(dòng)畫醉蚁,從而完成整個(gè)動(dòng)畫的繪制燃辖。由此可見,View動(dòng)畫其實(shí)是一個(gè)矩陣運(yùn)算的過程网棍。
優(yōu)缺點(diǎn)
優(yōu)勢:使用簡單黔龟,兼容性好
缺陷:
- 不具備交互性,View動(dòng)畫作用的實(shí)際上是View的影像,而非真正改變了View的屬性狀態(tài)氏身。也就是說巍棱,View動(dòng)畫結(jié)束后,即便使用setFillAfter(true)使得view保持在動(dòng)畫結(jié)束時(shí)的位置蛋欣,view的真實(shí)位置依舊未發(fā)生變化航徙,仍然處于最開始定義時(shí)的位置。因此陷虎,當(dāng)view動(dòng)畫結(jié)束后捉偏,其響應(yīng)位置仍然位于動(dòng)畫開始前的位置,這就使得其不具備交互性泻红;
- View動(dòng)畫只能作用于View對象夭禽,且提供的動(dòng)畫種類有限;
View動(dòng)畫的使用
通過Java代碼動(dòng)態(tài)創(chuàng)建動(dòng)畫
步驟:
- 創(chuàng)建TranslateAnimation谊路、RotateAnimation讹躯、ScaleAnimation或AlphaAnimation對象;
- 設(shè)置創(chuàng)建的動(dòng)畫對象的屬性缠劝,如動(dòng)畫執(zhí)行時(shí)間潮梯、延遲時(shí)間、起始位置惨恭、結(jié)束位置等秉馏;
- 通過View.startAnimation()方法開啟動(dòng)畫;
注:可以通過Animation.setAnimationListener()設(shè)置動(dòng)畫的監(jiān)聽器脱羡,監(jiān)聽動(dòng)畫的開始萝究、結(jié)束和重復(fù)狀態(tài),并在必要的時(shí)候添加自己的操作锉罐;
示例:
- 平移動(dòng)畫:
TranslateAnimation translate = new TranslateAnimation(0, 120, 0, 100);
translate.setFillAfter(true);
translate.setDuration(1000);
image.startAnimation(translate);
- 旋轉(zhuǎn)動(dòng)畫:
final RotateAnimation rotate1 = new RotateAnimation(0, 360); // 圍繞自己的左上角向右旋轉(zhuǎn)360度
final RotateAnimation rotate2 = new RotateAnimation(0, 90, Animation.RELATIVE_TO_PARENT, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f); // X軸坐標(biāo)向右偏移0.5倍父控件寬度帆竹,Y軸坐標(biāo)向下偏移0.5倍自身寬度,然后圍繞該點(diǎn)向右旋轉(zhuǎn)90度
rotate1.setDuration(1000); //設(shè)置動(dòng)畫時(shí)長
// 設(shè)置動(dòng)畫事件監(jiān)聽器
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); // 開始動(dòng)畫
+ 縮放動(dòng)畫:
```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);
- 透明度動(dòng)畫:
AlphaAnimation alpha = new AlphaAnimation(1, 0);
alpha.setDuration(1000);
alpha.setRepeatMode(Animation.REVERSE); //設(shè)置重復(fù)模式
alpha.setRepeatCount(5); //設(shè)置重復(fù)次數(shù)
image.startAnimation(alpha);
+ 動(dòng)畫集:
```Java
AnimationSet as = new AnimationSet(true); // 動(dòng)畫集共享插值器
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);
屬性解析:
- 動(dòng)畫的原點(diǎn)默認(rèn)為控件自身的左上角脓规,向右為X軸正向栽连,向下為Y軸正向
- 動(dòng)畫常見共有屬性:
- setInterpolator(Interpolator i):設(shè)置動(dòng)畫插值器(后面解釋),即設(shè)置動(dòng)畫的加速模式侨舆,默認(rèn)為線性插值器(勻速變化)秒紧,還可以設(shè)置為AccelerateDecelerateInterpolator、AccelerateInterpolator等挨下,或者自定義
- setFillAfter(boolean fillAfter): 動(dòng)畫結(jié)束后是否保持在結(jié)束狀態(tài)熔恢,true表示保持在結(jié)束時(shí)的狀態(tài),false表示返回開始前的狀態(tài)
- setFillBefore(boolean fillBefore):true表示動(dòng)畫結(jié)束時(shí)复颈,畫面停留在第一幀
- setDuration(long durationMillis):動(dòng)畫持續(xù)時(shí)長绩聘,單位:毫秒
- setRepeatCount(int repeatCount):動(dòng)畫重復(fù)次數(shù),-1表示無限循環(huán)
- setRepeatMode(int repeatMode):動(dòng)畫重復(fù)模式耗啦,為RESTART或REVERSE
- setStartTime(long startTimeMillis):動(dòng)畫開始時(shí)間凿菩,以毫秒表示
- setStartOffset(long startOffset):動(dòng)畫延遲時(shí)長,即延遲startOffset毫秒開始動(dòng)畫帜讲,當(dāng)startOffset>0時(shí)衅谷,動(dòng)畫開始時(shí)間為startTimeMillis+startOffset
- setZAdjustment(int zAdjustment):動(dòng)畫過程中Z軸方向的模式,默認(rèn)為normal
- 平移動(dòng)畫屬性:
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的三個(gè)構(gòu)造方法似将,最終均為了設(shè)置第三個(gè)構(gòu)造方法中的幾個(gè)參數(shù)所對應(yīng)的TranslateAnimation屬性值获黔,所以下面分別介紹這些屬性的含義。
fromXType 和 fromXValue:這倆屬性分別表示平移起點(diǎn)X軸方向的偏移類型和偏移量在验,fromXType有三種取值可選玷氏,分別為Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF 和 Animation.RELATIVE_TO_PARENT腋舌;
fromXType取值為Animation.ABSOLUTE時(shí)盏触,表示X軸方向的平移起點(diǎn)絕對平移fromXValue個(gè)像素點(diǎn),此時(shí)fromXValue為一個(gè)絕對像素值块饺;
fromXType取值為Animation.RELATIVE_TO_SELF時(shí)赞辩,表示X軸方向的平移起點(diǎn)相對自身平移fromXValue **** 控件寬度個(gè)像素點(diǎn),此時(shí)fromXValue為一個(gè)百分比值授艰,表示偏移量相對控件自身寬度的百分比辨嗽;
fromXType取值為Animation.RELATIVE_TO_PARENT 時(shí),表示X軸方向的平移起點(diǎn)相對父控件平移fromXValue **** 父控件寬度個(gè)像素點(diǎn)淮腾,此時(shí)fromXValue為一個(gè)百分比值糟需,表示偏移量相對父控件寬度的百分比;fromYType 和 fromYValue:分別表示平移起點(diǎn)Y軸方向的偏移類型和偏移量谷朝,具體含義同fromXType 和 fromXValue篮灼;
toXType 和 toXValue、toYType 和 toYValue:則表示終點(diǎn)位置的偏移量徘禁,具體含義同起點(diǎn)偏移量诅诱;
旋轉(zhuǎn)動(dòng)畫屬性:
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的四個(gè)構(gòu)造方法,其目的均為了設(shè)置fromDegrees送朱、toDegrees娘荡、pivotXType、pivotXValue驶沼、pivotYType炮沐、pivotYValue這幾個(gè)屬性值,下面對這幾個(gè)屬性分別進(jìn)行介紹回怜。
fromDegrees 和 toDegrees:這兩個(gè)屬性分別表示旋轉(zhuǎn)起始角度和終止角度大年;
-
pivotXType、pivotXValue、pivotYType翔试、pivotYValue:這四個(gè)屬性用于設(shè)置旋轉(zhuǎn)中心點(diǎn)位置轻要。
pivotXType 和 pivotXValue分別表示旋轉(zhuǎn)中心在X軸方向相對原點(diǎn)(即控件左上角)的偏移類型和偏移量,pivotXType有三個(gè)可選取值:Animation.ABSOLUTE垦缅、Animation.RELATIVE_TO_SELF 和 Animation.RELATIVE_TO_PARENT冲泥,分別表示絕對偏移、相對自身偏移和相對父控件偏移壁涎,當(dāng)取Animation.ABSOLUTE時(shí)凡恍,pivotXValue是一個(gè)絕對數(shù)值,否則pivotXValue是一個(gè)相對數(shù)值(取值為1表示100%)怔球。
pivotYType 和 pivotYValue:分別表示旋轉(zhuǎn)中心在Y軸方向相對原點(diǎn)的偏移類型和偏移量嚼酝,具體含義同pivotXType 和 pivotXValue。示例使用如下:
final RotateAnimation rotate2 = new RotateAnimation(0, 90, Animation.RELATIVE_TO_PARENT, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
// X軸坐標(biāo)向右偏移0.5倍父控件寬度竟坛,Y軸坐標(biāo)向下偏移0.5倍自身寬度革半,然后圍繞該點(diǎn)向右旋轉(zhuǎn)90度
- 縮放動(dòng)畫屬性:
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的四個(gè)構(gòu)造函數(shù),最終均為了設(shè)置ScaleAnimation的如下幾個(gè)屬性:
fromX流码、toX又官、fromY、 toY漫试、pivotXType六敬、pivotXValue、pivotYType 和 pivotYValue驾荣。
fromX 和 toX:這兩個(gè)屬性分別表示水平方向上相對自身的起始縮放因子和終止縮放因子外构,1表示100%,即原始大小播掷,因此水平方向縮放的總長度為(toX-fromX) * width
fromY 和 toY:這兩個(gè)屬性分別表示垂直方向上相對自身的起始縮放因子和終止縮放因子
-
pivotXType审编、pivotXValue、pivotYType 和 pivotYValue:這四個(gè)屬性用于控制縮放中心坐標(biāo)點(diǎn)位置歧匈。具體含義參見旋轉(zhuǎn)動(dòng)畫屬性說明部分垒酬。
示例使用如下:
ScaleAnimation scale = new ScaleAnimation(1, 1.5f, 1, 1.5f, Animation.RELATIVE_TO_PARENT, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
// 表示以X坐標(biāo)向右偏移0.5倍父控件寬度,Y坐標(biāo)向下偏移0.5倍自身高度的點(diǎn)為縮放中心點(diǎn)
// 將控件的水平和垂直方向分別從當(dāng)前寬高放大0.5倍
```
- 透明度動(dòng)畫屬性:
public AlphaAnimation(Context context, AttributeSet attrs)
public AlphaAnimation(float fromAlpha, float toAlpha)
如上為AlphaAnimation的兩個(gè)構(gòu)造方法件炉,主要看第二個(gè)構(gòu)造方法中的兩個(gè)屬性fromAlpha 和 toAlpha勘究,這兩個(gè)屬性分別表示動(dòng)畫開始時(shí)的透明度和結(jié)束時(shí)的透明度,0.0表示完全透明斟冕,即不可見口糕,1.0表示完全不透明。
示例使用如下:
AlphaAnimation alpha = new AlphaAnimation(1, 0);
// 表示將控件從不透明狀態(tài)調(diào)整到完全透明狀態(tài)
- 動(dòng)畫集(AnimationSet)屬性:
動(dòng)畫集用于將一組一起播放的動(dòng)畫組合為一個(gè)動(dòng)畫磕蛇。動(dòng)畫集從父類Animation中繼承的一些屬性的作用方式需要認(rèn)真加以理解景描,因?yàn)椴煌瑢傩缘谋憩F(xiàn)方式各異十办,有些屬性只作用于動(dòng)畫集自身,有些屬性會(huì)作用于動(dòng)畫集中的子動(dòng)畫超棺,而有些屬性又會(huì)被忽略向族。- duration, repeatMode, fillBefore, fillAfter: 當(dāng)為AnimationSet設(shè)置了這幾個(gè)屬性的時(shí)候,這幾個(gè)屬性將會(huì)作用于該動(dòng)畫集中的所有子動(dòng)畫中
- repeatCount, fillEnabled: 這兩個(gè)屬性在AnimationSet中不起作用说搅,將會(huì)被忽略炸枣;
- startOffset, shareInterpolator: 這兩個(gè)屬性將作用于AnimationSet自身