Android 動(dòng)畫之View動(dòng)畫

簡介

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)勢:使用簡單黔龟,兼容性好

缺陷:

  1. 不具備交互性,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)畫開始前的位置,這就使得其不具備交互性泻红;
  2. View動(dòng)畫只能作用于View對象夭禽,且提供的動(dòng)畫種類有限;

View動(dòng)畫的使用

通過Java代碼動(dòng)態(tài)創(chuàng)建動(dòng)畫

步驟:
  1. 創(chuàng)建TranslateAnimation谊路、RotateAnimation讹躯、ScaleAnimation或AlphaAnimation對象;
  2. 設(shè)置創(chuàng)建的動(dòng)畫對象的屬性缠劝,如動(dòng)畫執(zhí)行時(shí)間潮梯、延遲時(shí)間、起始位置惨恭、結(jié)束位置等秉馏;
  3. 通過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)畫坐標(biāo)系
  • 動(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屬性值获黔,所以下面分別介紹這些屬性的含義。

  • fromXTypefromXValue:這倆屬性分別表示平移起點(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è)百分比值糟需,表示偏移量相對父控件寬度的百分比;

  • fromYTypefromYValue:分別表示平移起點(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)行介紹回怜。

  • fromDegreestoDegrees:這兩個(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驾荣。

  • fromXtoX:這兩個(gè)屬性分別表示水平方向上相對自身的起始縮放因子和終止縮放因子外构,1表示100%,即原始大小播掷,因此水平方向縮放的總長度為(toX-fromX) * width

  • fromYtoY:這兩個(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自身

插值器

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末虏等,一起剝皮案震驚了整個(gè)濱河市弄唧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌霍衫,老刑警劉巖候引,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異敦跌,居然都是意外死亡澄干,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門柠傍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來麸俘,“玉大人,你說我怎么就攤上這事惧笛〈用模” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵患整,是天一觀的道長拜效。 經(jīng)常有香客問我,道長各谚,這世上最難降的妖魔是什么紧憾? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮昌渤,結(jié)果婚禮上赴穗,老公的妹妹穿的比我還像新娘。我一直安慰自己膀息,他們只是感情好望抽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著履婉,像睡著了一般煤篙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上毁腿,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天辑奈,我揣著相機(jī)與錄音苛茂,去河邊找鬼。 笑死鸠窗,一個(gè)胖子當(dāng)著我的面吹牛妓羊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播稍计,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼躁绸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了臣嚣?” 一聲冷哼從身側(cè)響起净刮,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎硅则,沒想到半個(gè)月后淹父,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡怎虫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年暑认,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片大审。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蘸际,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出徒扶,到底是詐尸還是另有隱情粮彤,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布酷愧,位于F島的核電站驾诈,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏溶浴。R本人自食惡果不足惜乍迄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望士败。 院中可真熱鬧闯两,春花似錦、人聲如沸谅将。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽饥臂。三九已至逊躁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間隅熙,已是汗流浹背稽煤。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工核芽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人酵熙。 一個(gè)月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓轧简,卻偏偏與公主長得像,于是被迫代替她去往敵國和親匾二。 傳聞我的和親對象是個(gè)殘疾皇子哮独,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容