Android中的動畫(XML方式)實(shí)踐(逐幀動畫與補(bǔ)間動畫)

Android提供了三種類型動畫:一開始的傳統(tǒng)動畫(包含兩種類型:逐幀動畫補(bǔ)間動畫(View動畫))和Android3.0 之后出現(xiàn)的

屬性動畫

逐幀動畫:基于單元格的動畫,每一幀顯示一個不同的drawable。一幀一幀的順序播放。

補(bǔ)間動畫:補(bǔ)間動畫應(yīng)用于view,通過對其位置,大小,旋轉(zhuǎn)和透明度的改變,讓view動起來。

屬性動畫:屬性動畫幾乎可以讓應(yīng)用程序中任何對象動起來。所有補(bǔ)間動畫的內(nèi)容,都可以通過屬性動畫實(shí)現(xiàn)。

下面逐一介紹:

注:這篇文章偏重于以xml方式實(shí)現(xiàn)相應(yīng)動畫效果。

逐幀動畫

逐幀動畫(Frame-by-frame Animations)從字面上理解就是一幀一幀的播放圖片,類似卡通動畫。

目標(biāo):

實(shí)現(xiàn)如下圖效果:

loading

步驟:

1.在res/drawable目錄下新建loading_frame.xml文件:

loading_frame.xml

根節(jié)點(diǎn)是animation-list,內(nèi)部由一到多個<item>節(jié)點(diǎn)組成,

oneshot屬性表示是否只播放一次(true:一次;false:循環(huán)播放).

item節(jié)點(diǎn)聲明是一個動畫幀,其中 android:drawable屬性定義要顯示的圖像,android:druation代表此幀持續(xù)的時間,毫秒為單位。

注:在AndroidStudio中強(qiáng)制規(guī)定帶animation-list節(jié)點(diǎn)xml文件必須放在res/drawable文件下(eclipse(ADT)貌似支持任意放res/drawable和res/anim)在androidStudio中若放在res/anim下會報(bào)錯:

錯誤提示:1
錯誤提示:2

2.新建頁面布局activity_frame.xml:如上圖布局很簡單 上面一個imageview,下面兩個button,都水平居中(相對于parent)。

? ?設(shè)置imageView背景為loading_frame: android:background="@drawable/loading_frame" ?這里就不貼代碼了。

3.新建FrameActivity

frameActivity主要邏輯代碼

當(dāng)然為了避免animationDrawable帶來的內(nèi)存泄露,建議在onDestroy方法中做如下操作:

onDestroy()

注意:

幀數(shù)比較多的動畫不建議用逐幀動畫實(shí)現(xiàn),其一會顯得卡頓,其二容易引起OOM

補(bǔ)間動畫

補(bǔ)間動畫(Tween Animation):支持通過對View的內(nèi)容進(jìn)行一系列的圖形變換來實(shí)現(xiàn)動畫效果。使用補(bǔ)間動畫進(jìn)行改變透明度、縮放、旋轉(zhuǎn)、平移等操作比通過手動重繪Canvas達(dá)到相似效果要消耗更少的資源,在實(shí)現(xiàn)上也更加簡便。

補(bǔ)間動畫類型對應(yīng)

補(bǔ)間動畫使用XML語言來定義時,其XML文件被放在項(xiàng)目的res/anim/目錄下。

由于相關(guān)的屬性有點(diǎn)多,在這先把它們公用的屬性做一下說明,然后再對每個分類下的特定屬性在做對應(yīng)動畫效果時,進(jìn)行描述。

屬性對應(yīng)方法及描述

在上面圖表中可以看到第二行有一個interpolator屬性,表示動畫所采用的插值器。插值器影響動畫的播放速度。可以不指定,默認(rèn)為加速減速插值器(@android:anim/accelerate_decelerate_interpolator")。

常用9種插值器

當(dāng)然安卓也支持自定義插值器,具體網(wǎng)上有許多相關(guān)博客教程,可自行搜索,這里先不作介紹。

說了這么多,都好像背書的趕腳了。下面我們來玩玩吧

漸變

1.在res/anim/目錄下新建view_alpha.xml

view_alpha.xml

(從頭播放重復(fù)一次)

這里有兩個屬性是alpha獨(dú)有的:

android:fromAlpha-動畫開始時操作對象的alpha值

android:toAlpha-動畫終止時操作對象的alpha值

2.在對應(yīng)view上應(yīng)用動畫

start_alpha

3.看一下運(yùn)行結(jié)果:

漸變—效果圖

由于默認(rèn)android:fillBefore為true,所以動畫運(yùn)行結(jié)束時會回到初始狀態(tài)

縮放

1.在res/anim/目錄下新建view_scale.xml

view_scale.xml

(反向播放重復(fù)兩次,保持最后狀態(tài))

屬性:

android:fromXScale-動畫起始時,X軸坐標(biāo)的伸縮尺寸。(0.0表示收縮到?jīng)]有。1.0表示正常沒伸縮。>1.0表示放大。<1.0表示收縮。)

android:toXScale-動畫結(jié)束時X軸坐標(biāo)的伸縮尺寸

android:fromYScale-動畫起始時Y軸坐標(biāo)的伸縮尺寸

android:toYScale-動畫結(jié)束時Y軸坐標(biāo)的伸縮尺寸

android:pivotX-縮放動畫作用點(diǎn)在X軸方向上的位置。(android:pivotX=”50”表示絕對定位,相對于零點(diǎn)偏移50 ? –>Animation.ABSOLUTE ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?android:pivotX=”50%”表示相對控件本身 ? ?–>Animation.RELATE_TO_SELF

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?android:pivotX=”50%p”表示相對控件的父控件 ?–>Animation.RELATE_TO_PARENT)

android:pivotY-縮放動畫作用點(diǎn)在Y軸方向上的位置(同上pivotX)


2.應(yīng)用動畫:

start-scale

3.運(yùn)行結(jié)果:

縮放-效果圖

旋轉(zhuǎn)

1.在res/anim/目錄下新建view_rotate.xml

view_rotate.xml

(運(yùn)行過程:先向相反的方向改變一點(diǎn),然后在加速播放至超出結(jié)束值一點(diǎn),然后在緩慢回到結(jié)束值)

屬性:

android:fromDegrees-動畫起始的角度(可正可負(fù))

android:toDegrees-動畫終止的角度(可正可負(fù))

android:pivotX-旋轉(zhuǎn)作用點(diǎn)在X軸方向上的位置

android:pivotY-旋轉(zhuǎn)作用點(diǎn)在Y軸方向上的位置

2.應(yīng)用動畫

start-rotate

3.運(yùn)行結(jié)果

旋轉(zhuǎn)-效果圖

平移

1.在res/anim/目錄下新建view_translate.xml:

view-translate.xml

(運(yùn)行過程:先向相反的方向改變一點(diǎn),然后在加速播放至超出結(jié)束值一點(diǎn),然后在緩慢回到結(jié)束值)

屬性:

android:fromXDelta-平移動畫起始位置X軸坐標(biāo) (android:fromXDelta=”50”表示絕對定位,相對于零點(diǎn)偏移50 ? –>Animation.ABSOLUTE

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? android:fromXDelta=”50%”表示相對控件本身 –>Animation.RELATE_TO_SELF

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?android:fromXDelta=”50%p”表示相對控件的父控件–>Animation.RELATE_TO_PARENT)

android:toXDelta-平移動畫結(jié)束位置X軸坐標(biāo)

android:fromYDelta-平移動畫起始位置Y軸坐標(biāo)

android:toYDelta-平移動畫結(jié)束位置Y軸坐標(biāo)

2.應(yīng)用

start-translate

3.運(yùn)行結(jié)果

平移-效果圖

組合

1.在res/anim/目錄下新建view_set.xml:

view_set.xml

屬性:

android:shareInterpolator-是否對子動畫設(shè)置相同的插值器

先來推測一下運(yùn)行過程:前1.5秒執(zhí)行漸變,然后圖片以自身中心為旋轉(zhuǎn)軸心,從60度轉(zhuǎn)到325度,耗時1.8s。

2.應(yīng)用

start-set

3.運(yùn)行效果:

組合-效果圖

額。。。跟當(dāng)初推測的不一致。它一開始就轉(zhuǎn)了60度然后再漸變,再轉(zhuǎn)到325度。也就是說吧<rotate>的初始狀態(tài)給先執(zhí)行了,因?yàn)槟J(rèn)的fillBefore屬性為true。好吧,在<rotate>中設(shè)置fillBefore為false,再試一次:

view_set.xml 修改后代碼段

再看看運(yùn)行效果---

組合-效果圖-1


沒有發(fā)生任何變化!!!!

是不是fillBefore失效了???看看源碼,進(jìn)去Animation類中,有一個mFillEabled變量(主要看上面注釋):

mFillEnabled

想到有個屬性android:fillEnabled 與fillBefore是否被忽略有關(guān),fillEnabled默認(rèn)值是false(這時fillBefore設(shè)置為false失效)。

那將android:fillEnabled設(shè)為true試試:

view_set.xml 再次修改后代碼段

看看效果:

組合-效果圖-終

OK ?要的就是這種效果(是不是很有朦朧美,哈哈)。


LayoutAnimation(View動畫特殊使用場景

? LayoutAnimation作用于ViewGroup,可控制其子元素的出場效果。經(jīng)常看到有些listview,它每個item都以動畫的形式出現(xiàn)。這里我們也來實(shí)現(xiàn)一個類似的功能吧!

1.為子元素指定入場動畫(在res/anim下新建anim_layout_item.xml)

anim_layout_item.xml

2.定義layoutAnimtion-res/anim下新建anim_layout.xml

anim_layout.xml

屬性:

android:delay - 先從字面意思理解就是延遲,具體什么意思 通過下面實(shí)現(xiàn) 再看

android:animationOrder - 動畫順序 有三種選項(xiàng) :normal,reverse,random ?具體各自有什么效果 通過下面實(shí)現(xiàn) 再看

android:animation 指定子元素具體動畫

3.為listview指定android:layoutAnimation屬性:

布局文件-lsitview片段

看看運(yùn)行結(jié)果:

delay-0-效果圖

貌似沒什么效果。那將anim_layout.xml中修改一下---android:delay="1",

delay-1-效果圖

從上面兩圖可以看到,當(dāng)delay=0時,各item同時出現(xiàn)在頁面中,當(dāng)delay=1時,各item是依次以設(shè)定的動畫方式出現(xiàn),細(xì)心一點(diǎn)看,幾乎當(dāng)上一個item到達(dá)最左部時(完成入場動畫),下一個item開始進(jìn)入視圖播放入場動畫。所以delay應(yīng)該指的是子元素的入場延遲。具體來說,第一個子元素延遲500ms*1(anim_layout_item.xml中設(shè)置duration=500,即子元素入場動畫周期為500ms)才開始播放入場動畫,第2個子元素延遲500ms*1*2播放入場動畫,以此類推。我們再來驗(yàn)證一下,將delay設(shè)置為0.5,推測應(yīng)該出現(xiàn)的效果為:上一個item大概到達(dá)中間位置時,下一個item開始入場:

delay-0.5-效果圖

delay的作用大概搞清楚了,下面來看看animationOrder的三個選項(xiàng):normal 上面幾個圖都是設(shè)為這個選項(xiàng)的,下面就只用看其他兩種選項(xiàng)下的運(yùn)行效果。

android:animationOrder="reverse"
android:animationOrder="random"

從上面幾個動圖的效果對比可以看到

android:animationOrder屬性是用來表示子元素動畫的順序的。默認(rèn)即為normal:順序顯示,排在前面item先開始入場;reverse:倒序;random:隨機(jī)。

當(dāng)然view動畫還可用于實(shí)現(xiàn)activity的切換效果等場景(5.0后,geogle推出的新的轉(zhuǎn)場動畫,還支持共享元素)。這里就不一一介紹了。


還有屬性動畫沒有介紹,屬性動畫非常強(qiáng)大,可以通過它實(shí)現(xiàn)絢麗的效果。鑒于它的相關(guān)內(nèi)容比較多,一時半會也說不完,下次有空再整理學(xué)習(xí)吧。


感謝:

https://developer.android.google.cn/guide/topics/graphics/view-animation.html

https://developer.android.google.cn/guide/topics/graphics/drawable-animation.html



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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