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

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

屬性動畫

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

補間動畫:補間動畫應(yīng)用于view,通過對其位置茧痒,大小雇庙,旋轉(zhuǎn)和透明度的改變鱼鼓,讓view動起來哪怔。

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

下面逐一介紹:

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

逐幀動畫

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

目標:

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

loading

步驟:

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

loading_frame.xml

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

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

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

注:在AndroidStudio中強制規(guī)定帶animation-list節(jié)點xml文件必須放在res/drawable文件下(eclipse(ADT)貌似支持任意放res/drawable和res/anim)铜秆。在androidStudio中若放在res/anim下會報錯:

錯誤提示: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ù)比較多的動畫不建議用逐幀動畫實現(xiàn)巍糯,其一會顯得卡頓啸驯,其二容易引起OOM

補間動畫

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

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

補間動畫使用XML語言來定義時厌衙,其XML文件被放在項目的res/anim/目錄下距淫。

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

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

在上面圖表中可以看到第二行有一個interpolator屬性喻杈,表示動畫所采用的插值器。插值器影響動畫的播放速度奕塑∶瞬可以不指定歹茶,默認為加速減速插值器(@android:anim/accelerate_decelerate_interpolator")禽作。

常用9種插值器

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

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

漸變

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

view_alpha.xml

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

這里有兩個屬性是alpha獨有的:

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

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

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

start_alpha

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

漸變—效果圖

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

縮放

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

view_scale.xml

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

屬性:

android:fromXScale-動畫起始時匀们,X軸坐標的伸縮尺寸。(0.0表示收縮到?jīng)]有准给。1.0表示正常沒伸縮。>1.0表示放大重抖。<1.0表示收縮露氮。)

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

android:fromYScale-動畫起始時Y軸坐標的伸縮尺寸

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

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

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

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

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


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

start-scale

3.運行結(jié)果:

縮放-效果圖

旋轉(zhuǎn)

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

view_rotate.xml

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

屬性:

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

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

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

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

2.應(yīng)用動畫

start-rotate

3.運行結(jié)果

旋轉(zhuǎn)-效果圖

平移

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

view-translate.xml

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

屬性:

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

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

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

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

android:fromYDelta-平移動畫起始位置Y軸坐標

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

2.應(yīng)用

start-translate

3.運行結(jié)果

平移-效果圖

組合

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

view_set.xml

屬性:

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

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

2.應(yīng)用

start-set

3.運行效果:

組合-效果圖

額对室。。咖祭。跟當(dāng)初推測的不一致掩宜。它一開始就轉(zhuǎn)了60度然后再漸變,再轉(zhuǎn)到325度么翰。也就是說吧<rotate>的初始狀態(tài)給先執(zhí)行了牺汤,因為默認的fillBefore屬性為true。好吧浩嫌,在<rotate>中設(shè)置fillBefore為false檐迟,再試一次:

view_set.xml 修改后代碼段

再看看運行效果---

組合-效果圖-1


沒有發(fā)生任何變化4饕选!9酢糖儡!

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

mFillEnabled

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

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

view_set.xml 再次修改后代碼段

看看效果:

組合-效果圖-終

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


LayoutAnimation(View動畫特殊使用場景

? LayoutAnimation作用于ViewGroup金闽,可控制其子元素的出場效果。經(jīng)辰斯牵看到有些listview代芜,它每個item都以動畫的形式出現(xiàn)。這里我們也來實現(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 - 先從字面意思理解就是延遲挤庇,具體什么意思 通過下面實現(xiàn) 再看

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

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

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

布局文件-lsitview片段

看看運行結(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)昆咽,細心一點看,幾乎當(dāng)上一個item到達最左部時(完成入場動畫)牙甫,下一個item開始進入視圖播放入場動畫掷酗。所以delay應(yīng)該指的是子元素的入場延遲。具體來說窟哺,第一個子元素延遲500ms*1(anim_layout_item.xml中設(shè)置duration=500泻轰,即子元素入場動畫周期為500ms)才開始播放入場動畫,第2個子元素延遲500ms*1*2播放入場動畫脏答,以此類推糕殉。我們再來驗證一下,將delay設(shè)置為0.5殖告,推測應(yīng)該出現(xiàn)的效果為:上一個item大概到達中間位置時阿蝶,下一個item開始入場:

delay-0.5-效果圖

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

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

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

android:animationOrder屬性是用來表示子元素動畫的順序的。默認即為normal:順序顯示爽丹,排在前面item先開始入場筑煮;reverse:倒序辛蚊;random:隨機。

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


還有屬性動畫沒有介紹秸应,屬性動畫非常強大虑凛,可以通過它實現(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)系作者
  • 序言:七十年代末祸挪,一起剝皮案震驚了整個濱河市锣披,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贿条,老刑警劉巖雹仿,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異闪唆,居然都是意外死亡盅粪,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門悄蕾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人础浮,你說我怎么就攤上這事帆调。” “怎么了豆同?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵番刊,是天一觀的道長。 經(jīng)常有香客問我影锈,道長芹务,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任鸭廷,我火速辦了婚禮枣抱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘辆床。我一直安慰自己佳晶,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布讼载。 她就那樣靜靜地躺著轿秧,像睡著了一般中跌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上菇篡,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天漩符,我揣著相機與錄音,去河邊找鬼驱还。 笑死嗜暴,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的铝侵。 我是一名探鬼主播灼伤,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼咪鲜!你這毒婦竟也來了狐赡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤疟丙,失蹤者是張志新(化名)和其女友劉穎颖侄,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體享郊,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡览祖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了炊琉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片展蒂。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖苔咪,靈堂內(nèi)的尸體忽然破棺而出锰悼,到底是詐尸還是另有隱情,我是刑警寧澤团赏,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布箕般,位于F島的核電站,受9級特大地震影響舔清,放射性物質(zhì)發(fā)生泄漏丝里。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一体谒、第九天 我趴在偏房一處隱蔽的房頂上張望杯聚。 院中可真熱鬧,春花似錦营密、人聲如沸械媒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纷捞。三九已至痢虹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間主儡,已是汗流浹背奖唯。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留糜值,地道東北人丰捷。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓歧寺,卻偏偏與公主長得像匣砖,于是被迫代替她去往敵國和親蚊丐。 傳聞我的和親對象是個殘疾皇子婉烟,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,066評論 2 355

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