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)如下圖效果:
步驟:
1.在res/drawable目錄下新建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下會報錯:
2.新建頁面布局activity_frame.xml:如上圖布局很簡單 上面一個imageview,下面兩個button,都水平居中(相對于parent)讶迁。
? ?設(shè)置imageView背景為loading_frame: android:background="@drawable/loading_frame" ?這里就不貼代碼了连茧。
3.新建FrameActivity
當(dāng)然為了避免animationDrawable帶來的內(nèi)存泄露,建議在onDestroy方法中做如下操作:
注意:
幀數(shù)比較多的動畫不建議用逐幀動畫實現(xiàn)巍糯,其一會顯得卡頓啸驯,其二容易引起OOM。
補間動畫
補間動畫(Tween Animation):支持通過對View的內(nèi)容進行一系列的圖形變換來實現(xiàn)動畫效果祟峦。使用補間動畫進行改變透明度罚斗、縮放、旋轉(zhuǎn)宅楞、平移等操作比通過手動重繪Canvas達到相似效果要消耗更少的資源针姿,在實現(xiàn)上也更加簡便。
補間動畫使用XML語言來定義時厌衙,其XML文件被放在項目的res/anim/目錄下距淫。
由于相關(guān)的屬性有點多,在這先把它們公用的屬性做一下說明婶希,然后再對每個分類下的特定屬性在做對應(yīng)動畫效果時榕暇,進行描述。
在上面圖表中可以看到第二行有一個interpolator屬性喻杈,表示動畫所采用的插值器。插值器影響動畫的播放速度奕塑∶瞬可以不指定歹茶,默認為加速減速插值器(@android:anim/accelerate_decelerate_interpolator")禽作。
當(dāng)然安卓也支持自定義插值器,具體網(wǎng)上有許多相關(guān)博客教程嗤堰,可自行搜索后专,這里先不作介紹。
說了這么多疏唾,都好像背書的趕腳了蓄氧。下面我們來玩玩吧
漸變
1.在res/anim/目錄下新建view_alpha.xml
(從頭播放重復(fù)一次)
這里有兩個屬性是alpha獨有的:
android:fromAlpha-動畫開始時操作對象的alpha值
android:toAlpha-動畫終止時操作對象的alpha值
2.在對應(yīng)view上應(yīng)用動畫:
3.看一下運行結(jié)果:
由于默認android:fillBefore為true,所以動畫運行結(jié)束時會回到初始狀態(tài)
縮放
1.在res/anim/目錄下新建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)用動畫:
3.運行結(jié)果:
旋轉(zhuǎn)
1.在res/anim/目錄下新建view_rotate.xml
(運行過程:先向相反的方向改變一點畔规,然后在加速播放至超出結(jié)束值一點,然后在緩慢回到結(jié)束值)
屬性:
android:fromDegrees-動畫起始的角度(可正可負)
android:toDegrees-動畫終止的角度(可正可負)
android:pivotX-旋轉(zhuǎn)作用點在X軸方向上的位置
android:pivotY-旋轉(zhuǎn)作用點在Y軸方向上的位置
2.應(yīng)用動畫
3.運行結(jié)果
平移
1.在res/anim/目錄下新建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)用
3.運行結(jié)果
組合
1.在res/anim/目錄下新建view_set.xml:
屬性:
android:shareInterpolator-是否對子動畫設(shè)置相同的插值器
先來推測一下運行過程:前1.5秒執(zhí)行漸變畜埋,然后圖片以自身中心為旋轉(zhuǎn)軸心莫绣,從60度轉(zhuǎn)到325度,耗時1.8s悠鞍。
2.應(yīng)用
3.運行效果:
額对室。。咖祭。跟當(dāng)初推測的不一致掩宜。它一開始就轉(zhuǎn)了60度然后再漸變,再轉(zhuǎn)到325度么翰。也就是說吧<rotate>的初始狀態(tài)給先執(zhí)行了牺汤,因為默認的fillBefore屬性為true。好吧浩嫌,在<rotate>中設(shè)置fillBefore為false檐迟,再試一次:
再看看運行效果---
是不是fillBefore失效了???看看源碼,進去Animation類中,有一個mFillEabled變量(主要看上面注釋):
想到有個屬性android:fillEnabled 與fillBefore是否被忽略有關(guān)怔匣,fillEnabled默認值是false(這時fillBefore設(shè)置為false失效)握联。
那將android:fillEnabled設(shè)為true試試:
看看效果:
OK ?要的就是這種效果(是不是很有朦朧美,哈哈)每瞒。
LayoutAnimation(View動畫特殊使用場景)
? LayoutAnimation作用于ViewGroup金闽,可控制其子元素的出場效果。經(jīng)辰斯牵看到有些listview代芜,它每個item都以動畫的形式出現(xiàn)。這里我們也來實現(xiàn)一個類似的功能吧浓利!
1.為子元素指定入場動畫(在res/anim下新建anim_layout_item.xml)
2.定義layoutAnimtion-res/anim下新建anim_layout.xml
屬性:
android:delay - 先從字面意思理解就是延遲挤庇,具體什么意思 通過下面實現(xiàn) 再看
android:animationOrder - 動畫順序 有三種選項 :normal,reverse,random ?具體各自有什么效果 通過下面實現(xiàn) 再看
android:animation 指定子元素具體動畫
3.為listview指定android:layoutAnimation屬性:
看看運行結(jié)果:
貌似沒什么效果。那將anim_layout.xml中修改一下---android: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的作用大概搞清楚了,下面來看看animationOrder的三個選項:normal 上面幾個圖都是設(shè)為這個選項的黄绩,下面就只用看其他兩種選項下的運行效果羡洁。
從上面幾個動圖的效果對比可以看到
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