關(guān)于Android的幾種基本動(dòng)畫

一直以來各種動(dòng)畫效果也只是零碎地在需要用到的時(shí)候復(fù)制粘貼祝闻,或者直接自己Draw一遍占卧,并且記下一些零碎的代碼段。然而最近比賽項(xiàng)目又碰到了需要各種動(dòng)畫過場(chǎng)的情況联喘,想想這問題也是積攢已久了华蜒,于是準(zhǔn)備認(rèn)真的學(xué)習(xí)一下。

? 首先豁遭,Android里的動(dòng)畫分為三種:PropertyAnimation(屬性動(dòng)畫)叭喜、ViewAnimation(視圖動(dòng)畫)DrawableAnimation(幀動(dòng)畫,By the way蓖谢,官網(wǎng)中翻是可繪制動(dòng)畫捂蕴,感覺就很不對(duì)勁 -_-)。其中屬性動(dòng)畫在API 11之后加入闪幽,它可以對(duì)所有對(duì)象(包括未渲染到屏幕的對(duì)象)添加動(dòng)畫效果啥辨,拓展性強(qiáng)且特點(diǎn)多樣,是官方推薦的動(dòng)畫實(shí)現(xiàn)手段盯腌;視圖動(dòng)畫則是比較老的動(dòng)畫實(shí)現(xiàn)手段溉知,其僅對(duì)View起效,并且只有視覺上的變化,而不實(shí)際改變View的位置或其他真實(shí)屬性级乍;可繪制動(dòng)畫則適用于借助Drawable資源實(shí)現(xiàn)的情景舌劳,通過切換幀實(shí)現(xiàn)動(dòng)畫效果,比如常見的進(jìn)度條旋轉(zhuǎn)與游戲中人物走動(dòng)效果等卡者。下面依次說一下各個(gè)動(dòng)畫的用法蒿囤。

視圖動(dòng)畫

? 首先講講ViewAnimation,為什么不是PropertyAnimation崇决?大概是因?yàn)樗奈臋n比較短.(PropertyAnimation:明明是我先材诽,出現(xiàn)在正文也好,官方推薦也好...)恒傻。記得當(dāng)年年輕的我某一日終于忍受不了各種View硬生生直挺挺地在面前排布時(shí)脸侥,怒而百度,第一個(gè)搜出來的教程就是關(guān)于它的盈厘,然后我就實(shí)現(xiàn)了Coding以來第一個(gè)動(dòng)畫:一個(gè)很蠢的點(diǎn)擊按鈕旋轉(zhuǎn)滾動(dòng)拉出一個(gè)EditText的動(dòng)畫睁枕。ViewAnimation實(shí)際上是為了在View上實(shí)現(xiàn)TweenedAnimation,即補(bǔ)間動(dòng)畫(這個(gè)名詞在各種教程技術(shù)文里出現(xiàn)的頻率明顯也更高)沸手。它的實(shí)現(xiàn)效果就是簡(jiǎn)單地設(shè)置View進(jìn)行自定義起始點(diǎn)和結(jié)束點(diǎn)的平移外遇、旋轉(zhuǎn)、大小和透明度變換等等契吉,能夠用XML與Java代碼兩種方式實(shí)現(xiàn)跳仿,官方推薦是用XML文件(位于res/anim下)實(shí)現(xiàn),這樣會(huì)使代碼結(jié)構(gòu)看起來更清晰捐晶。下面是XML代碼的各種屬性和格式:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@[package:]anim/interpolator_resource"http://插值器類型菲语,可以設(shè)置在單獨(dú)的動(dòng)畫效果中
    android:shareInterpolator=["true" | "false"] >
    <alpha//設(shè)置不透明度,值為0f-1.0f
        android:fromAlpha="float"
        android:toAlpha="float" />
    <scale//設(shè)置大小
        //縮放比例惑灵,1.0f為無變化
        android:fromXScale="float"
        android:toXScale="float"
        android:fromYScale="float"
        android:toYScale="float"
        //縮放中心
        android:pivotX="float" 
        android:pivotY="float" />
    <translate//設(shè)置平移
        //以下值的表示規(guī)則為:普通float無后綴數(shù)字山上,如“50”,表示絕對(duì)偏移值英支;-100 - 100以“%”為后綴的值佩憾,如“50%”,表示相對(duì)自身位置的偏移值干花;-100 - 100以“%p”為后綴值妄帘,如“50%p”,表示相對(duì)父布局的偏移值把敢。
        android:fromXDelta="float"
        android:toXDelta="float"
        android:fromYDelta="float"
        android:toYDelta="float" />
    <rotate//設(shè)置旋轉(zhuǎn)
        //旋轉(zhuǎn)角度,單位為度谅辣,正方向?yàn)轫槙r(shí)針
        android:fromDegrees="float"
        android:toDegrees="float"
        //旋轉(zhuǎn)中心修赞,與上面偏移值的表示規(guī)則相同,分別以無后綴、“%”與“%p”分別表示其與View邊緣(左和上)的絕對(duì)值柏副,與View邊緣的相對(duì)百分比(50%勾邦,50%則為正中心),與父布局邊緣的相對(duì)百分比割择。
        android:pivotX="float"
        android:pivotY="float" />
    <set>
        ...
    </set>
</set>

另外它們都有繼承自Animation的通用屬性:

屬性名 說明 參數(shù)類型
android:detachWallpaper 窗口動(dòng)畫的特殊選項(xiàng)眷篇,當(dāng)窗口處于壁紙之上時(shí),選擇是否讓壁紙與其一起運(yùn)動(dòng) boolean
android:duration 動(dòng)畫的執(zhí)行時(shí)間荔泳,以毫秒為單位蕉饼,默認(rèn)為300ms integer
android:fillAfter 為true時(shí),動(dòng)畫變換效果將保持玛歌。(僅在set中設(shè)置有效) boolean
android:fillBefore 為true時(shí)昧港,動(dòng)畫運(yùn)行結(jié)束后停留在第一幀。默認(rèn)為true支子。 boolean
android:fillEnabled 設(shè)為true時(shí) fiilBefore才有效创肥,為false且動(dòng)畫未設(shè)置給View時(shí),讓fillAfter為true boolean
android:interpolator 設(shè)置相應(yīng)插值器值朋。 refrence
android:repeatCount 設(shè)置動(dòng)畫重復(fù)次數(shù) integer
android:repeatMode 動(dòng)畫播完一遍再重復(fù)時(shí)的行為模式叹侄,有restart和reverse兩種模式。 string
android:startOffset 動(dòng)畫開始前的延遲時(shí)間昨登,以毫秒為單位淆储。 integer
android:zAdjustment 允許調(diào)整在動(dòng)畫持續(xù)時(shí)間內(nèi)動(dòng)畫的內(nèi)容的Z排序步藕。有bottom(ffffff)、normal(0)與top(1)三種模式,默認(rèn)為normal(保持現(xiàn)有順序)淤翔。 integer

關(guān)于上面的interpolator,有如下系統(tǒng)默認(rèn)調(diào)用:

名稱 資源ID 說明
AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 開始和結(jié)束較慢中間加快饶唤。
AccelerateInterpolator @android:anim/accelerate_interpolator 開始較慢肄程,之后加速。
AnticipateInterpolator @android:anim/anticipate_interpolator 先減速再加速得湘。
AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 先減速再加速直致越界杖玲,最后回到原速。
BounceInterpolator @android:anim/bounce_interpolator 上下起伏到后面趨于平坦淘正。
CycleInterpolator @android:anim/cycle_interpolator 重復(fù)動(dòng)畫指定的循環(huán)次數(shù)摆马。 變化率遵循正弦曲線。(也就是有正有負(fù)鸿吆,可以制造回彈效果)
DecelerateInterpolator @android:anim/decelerate_interpolator 減速變化
LinearInterpolator @android:anim/linear_interpolator 線性變化
OvershootInterpolator @android:anim/overshoot_interpolator 減速增長(zhǎng)然后越界囤采,回歸原點(diǎn)。

上面的插值變化實(shí)際表示各種速度變化曲線惩淳,可以參考blog中的圖參考圖例

在寫好動(dòng)畫相關(guān)函數(shù)后可以用Java代碼調(diào)用:

Animation anim = AnimationUtils.loadAnimate(context,R.anim.demo);
//方式一
view.startAnimation(anim);//立即開始動(dòng)畫蕉毯,考慮上面的startOffset屬性
//方式二
anim.setStartTime(time)//設(shè)置動(dòng)畫開始時(shí)間乓搬,參數(shù)是格林威治時(shí)間至今的毫秒數(shù)
view.setAnimation(anim);//設(shè)置動(dòng)畫,當(dāng)其動(dòng)畫時(shí)間到達(dá)時(shí)則自然開始動(dòng)畫代虾。

另外进肯,需要注意的地方有:一、set內(nèi)的所有動(dòng)畫默認(rèn)都是同時(shí)運(yùn)行的棉磨,所以當(dāng)需要?jiǎng)赢嬘邢群箜樞驎r(shí)需要用startOffset來進(jìn)行延遲播放江掩。二、位移或者放大類動(dòng)畫并不會(huì)拓展View本身的空間乘瓤,當(dāng)其越界時(shí)环形,便不會(huì)顯示在界面上。三馅扣、ViewAnimation并不會(huì)改變View的真實(shí)屬性斟赚,當(dāng)其由于動(dòng)畫效果不處于本身的位置時(shí),其事實(shí)上的點(diǎn)擊區(qū)域還是在原地差油。(所以在知道屬性動(dòng)畫之前拗军,我一直都是用兩個(gè)不同時(shí)出現(xiàn)的按鈕實(shí)現(xiàn)的一開始提到的那個(gè)滾動(dòng)出EditText的效果,真的很蠢蓄喇。发侵。)

關(guān)于屬性動(dòng)畫

? 由于視圖動(dòng)畫的純“花架子”式動(dòng)畫效果,在更多需要和動(dòng)畫界面交互的場(chǎng)景中妆偏,屬性動(dòng)畫后來的上位也就不難理解了刃鳄。它的構(gòu)成部分主要有這么幾項(xiàng):ValueAnimator、 TimeInterpolator和TypeEvaluator钱骂,下面先進(jìn)行一下概述叔锐。

? ValueAnimator是整個(gè)屬性動(dòng)畫系統(tǒng)的核心基類,其中包含了動(dòng)畫的起止時(shí)間见秽,屬性變化規(guī)律和監(jiān)聽等功能愉烙,負(fù)責(zé)維護(hù)整個(gè)動(dòng)畫的運(yùn)行流程,其下子類ObjectAnimator是最常用到的屬性動(dòng)畫實(shí)現(xiàn)類解取,可以為任意對(duì)象加載動(dòng)畫效果步责,另外還有AnimatorSet,其類似XML文件內(nèi)的<set>標(biāo)簽禀苦,表示一組動(dòng)畫蔓肯。

? TimeInterpolatorTypeEvaluator事實(shí)上也不是什么新東西了,在ViewAnimation中也有相同的機(jī)制振乏,它們的運(yùn)行機(jī)制簡(jiǎn)單來說是這樣的:當(dāng)Animator設(shè)定了動(dòng)畫的起止時(shí)間并執(zhí)行start()之后蔗包,之后動(dòng)畫的每一幀都會(huì)根據(jù)開始時(shí)間與當(dāng)前時(shí)間的差與總時(shí)間的比值通過TimeInterpolator得到相應(yīng)的0-1.0間的值,然后TypeEvaluator得到這個(gè)值并由此估算出此時(shí)對(duì)象應(yīng)具有的屬性慧邮,并更新其屬性值调限,如此循環(huán)直至動(dòng)畫結(jié)束邻储。所以這一對(duì)其實(shí)就是控制動(dòng)畫播放速度(視覺上的,總時(shí)間是一定的)的工具旧噪。

接下來就是各種例子嘍,首先是ValueAnimator:

它的初始化方法有幾種脓匿,如下:

ValueAnimator animator = ValueAnimator.ofInt(startValue,endValue);
ValueAnimator animator = ValueAnimator.ofFloat(startValue,endValue);
ValueAnimator animator = ValueAnimator.ofArgb(startValue,endValue);//必須為8位ARGB值淘钟,且必須為兩個(gè)值
ValueAnimator animator = ValueAnimator.ofObject(evaluator,startValue,endValue);//這里的兩個(gè)value都是Object類型的。
Keyframe kf0 = Keyframe.ofFloat(time1, value1);//關(guān)鍵幀陪毡,記錄了在指定的time時(shí)其應(yīng)有的value米母,可以定義自己的Interceptor
Keyframe kf1 = Keyframe.ofFloat(time2, value2);
Keyframe kf2 = Keyframe.ofFloat(time3, value3);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
//"rotation"在ValueAnimator中僅僅是一個(gè)屬性的名字,只在在getAnimationValue(name)時(shí)可能會(huì)使用到毡琉,但在ObjectAnimator中就代表目標(biāo)對(duì)象的屬性
ValueAnimator rotationAnim = ValueAnimator.ofPropertyValuesHolder(pvhRotation)

//以上所有startValue 和 endValue都是可變參數(shù)铁瞒,只填一個(gè)的話會(huì)默認(rèn)從0開始,然后將填入的值為終點(diǎn)值桅滋,當(dāng)然填多個(gè)的話也沒有任何問題慧耍,甚至可以填入一串值實(shí)現(xiàn)來回變化屬性的效果
//ofInt,ofFloat 和ofArgb只是決定了TimeInterpolator計(jì)算得到的參數(shù)類型丐谋,并不影響最終結(jié)果芍碧,影響結(jié)果的永遠(yuǎn)是Evaluator

然而ValueAnimator并沒有預(yù)設(shè)的屬性動(dòng)畫效果,官網(wǎng)上給的例子是通過addUpdateListener監(jiān)聽來自己更改View屬性的(當(dāng)然所有對(duì)象都一樣号俐,反正都是自定義)泌豆,下面是一個(gè)比較完整的一個(gè)例子:

ValueAnimator animator = ValueAnimator.ofObject(new TypeEvaluator() {
            @Override
            public Object evaluate(float fraction, Object startValue, Object endValue) {
                return fraction*(int)endValue; //這里的算法可以隨便定義,甚至可以完全不管       TimeInterpolator傳來的fraction數(shù)值吏饿,返回值就是getAnimatedValue能拿到的值踪危。
            }
        },0, 100);
        animator.setDuration(1000);
        animator.setInterpolator(new CycleInterpolator(5));//隨便設(shè)置了一個(gè)插值器,上面有說明
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                //注意猪落,動(dòng)畫的每一幀耗費(fèi)的時(shí)間是不確定的贞远,所以這里得到的值在線性插值器條件下也只是近似線性
                view.setTranslationX((float)animation.getAnimatedValue());
            }
        });
        animator.start();//即時(shí)開始動(dòng)畫,也可以用setStartDelay進(jìn)行一下延時(shí)

為了簡(jiǎn)化ValueAnimator的使用(畢竟老是得寫匿名類監(jiān)聽還是挺占地方的)许布,ObjectAnimator便站了出來兴革,它的使用如下:

ObjectAnimator animator = ObjectAnimator.ofFloat(view,"scaleX",0.1f);
animator.setDuration(1000);
animator.start();
//大部分方法繼承自ValueAnimator,就不寫了

需要注意的是蜜唾,ObjectAnimator的工廠方法第一個(gè)參數(shù)與ValueAnimator 不同杂曲,它需要傳入一個(gè)Object(可以認(rèn)為是一個(gè)Java Bean)以及其相關(guān)屬性,在之后的屬性更新操作中袁余,會(huì)通過反射調(diào)用Object的setter和getter方法來更改屬性擎勘,要求相關(guān)Object類中必須有setter和getter方法(如屬性字段size,需要在Object類中定義setSize和getSize方法颖榜,方法參數(shù)與返回值必須與傳入數(shù)據(jù)類型相同)棚饵,若無法控制Object的方法煤裙,則要做一個(gè)符合要求的包裝類。對(duì)于View噪漾,除了上面的scaleX硼砰,還有幾個(gè)常用的預(yù)定義屬性:translationX和translationY,rotation(繞中心在水平面內(nèi)順時(shí)針旋轉(zhuǎn)) rotationX(繞X軸在立體面內(nèi)旋轉(zhuǎn))和rotationY(繞Y軸在立體面內(nèi)旋轉(zhuǎn))欣硼,pivotX和pivotY(設(shè)置縮放與平移的中心题翰,默認(rèn)為View中心),alpha以及backgroundColor等View屬性诈胜,Android實(shí)際上對(duì)其也做了一層封裝豹障,即ViewPropertyAnimator類:

view.animate().scaleX(0.5f).scaleY(0.5f).duration(1000).start();//默認(rèn)以中心縮小一倍
view.animate().translationY(200).duration(1000).start();//向下移動(dòng)200px
view.animate().alpha(0f).duration(1000).start();//從當(dāng)前透明度變至完全透明
//注意,這里的所有動(dòng)畫都是有絕對(duì)的默認(rèn)中心的焦匈。而當(dāng)運(yùn)行過前面的動(dòng)畫后血公,默認(rèn)中心仍不會(huì)變。如translationY(200)后回到原位置的方式并不是translationY(-200),而是translationY(0)

關(guān)于AnimatorSet主要是幾個(gè)動(dòng)畫調(diào)度方法:

AnimatorSet set = new AnimatorSet();
set.playSequentially(anim1,anim2,anim3);//在start后順序播放參數(shù)列表內(nèi)的動(dòng)畫
set.playTogether(anim1,anim2,anim3);//在start后同時(shí)播放參數(shù)列表內(nèi)的動(dòng)畫
//AnimatorSet.Builder調(diào)用
set.play(anim1).with(anim2);//start后同時(shí)播放動(dòng)畫1和動(dòng)畫2
set.play(anim2).before(anim3);//在播放動(dòng)畫2之后播放動(dòng)畫3
set.play(anim4).after(anim3);//在播放動(dòng)畫3之后播放動(dòng)畫4
set.play(anim4).after(1000);//在start后1秒播放動(dòng)畫4
set.start();
//注意缓熟,上面的鏈?zhǔn)秸{(diào)用相鄰鏈之間是并列關(guān)系累魔,如set.play(anim1).before(anim2).before(anim3)播放順序?yàn)閯?dòng)畫1先播放,動(dòng)畫2和動(dòng)畫3同時(shí)播放

其實(shí)如果僅是同時(shí)運(yùn)行的話够滑,用上面出現(xiàn)過的PropertyValuesHolder也能實(shí)現(xiàn)與AnimatorSet相似的效果:

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();//這里的工廠方法仍然是可變參數(shù)的方法薛夜,所以可以添加多個(gè)動(dòng)畫同時(shí)運(yùn)行

與ViewAnimation相同,PropertyAnimation也能通過XML文件定義版述,文件存放在res/animator目錄下以跟原來的animation區(qū)分梯澜,其對(duì)應(yīng)上面三個(gè)類的標(biāo)簽分別為<animator> <objectAnimator>和<set>,其相關(guān)定義如下:

<set
  android:ordering=["together" | "sequentially"]> //共同運(yùn)行(默認(rèn))和順序執(zhí)行

    <objectAnimator
        android:propertyName="string" //屬性名,如alpha渴析,background等屬性
        android:duration="int"  //運(yùn)行時(shí)長(zhǎng)
        android:valueFrom="float | int | color"  //起始值
        android:valueTo="float | int | color" //終點(diǎn)值
        android:startOffset="int" //起始時(shí)間延遲
        android:repeatCount="int"  //重復(fù)次數(shù)晚伙,-1為無限重復(fù),0為不重復(fù)
        android:repeatMode=["repeat" | "reverse"] //重復(fù)模式俭茧,順序或倒序咆疗,僅在repeatCount為正數(shù)或-1時(shí)起效
        android:valueType=["intType" | "floatType"]/> //值類型,關(guān)系到后面估值器的返回值

    <animator
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>

    <set>
        ...
    </set>
</set>

在定義了XML后母债,在Java代碼中調(diào)用:

//調(diào)用ValueAnimator
ValueAnimator animator = (ValueAnimator)AnimatorInflater(context,R.animator.anim);
animator.addUpdateListener(mListener);//在監(jiān)聽里更新屬性
animator.start();
//調(diào)用ObjectAnimator
ObjectAnimator animator = (ObjectAnimator)AnimatorInflater(context,R.animaror.anim);
animator.setTarget(view);//設(shè)置作用對(duì)象午磁,此時(shí)該對(duì)象必須含有propertyName屬性以及其setter getter方法
animator.start();
//調(diào)用AnimatorSet
AnimatorSet set = (AnimatorSet)AnimatorInflater(context,R.animtor.anim);
set.setTarget(view);//這里主要是set里的動(dòng)畫為ObjectAnimator的情況,事實(shí)上將ValueAnimator放在set里是沒有意義的毡们,因?yàn)閟et中沒有相關(guān)的更新回調(diào)方法迅皇,沒有辦法更新ValueAnimator指定的屬性
set.start();

至此屬性動(dòng)畫的基本使用都說完了。不過上面寫到的動(dòng)畫效果都是需要人為調(diào)用的衙熔,事實(shí)上Android還提供了一些在特定情景下自動(dòng)調(diào)用的動(dòng)畫效果登颓,這就是 以LayoutTransition表現(xiàn)的布局動(dòng)畫()。

添加布局動(dòng)畫的方式很簡(jiǎn)單红氯,只要在XML文件中的某個(gè)ViewGroup標(biāo)簽下加上一行:

android:animateLayoutChanges="true"

則當(dāng)布局發(fā)生變化(一般是add框咙、remove咕痛、setVisibility等情況下)時(shí),就會(huì)有默認(rèn)的控件fade或者上滑等效果喇嘱。在源碼中可以看到茉贡,當(dāng)這個(gè)值為true時(shí),ViewGroup便設(shè)置了一個(gè)LayoutTransition:

case R.styleable.ViewGroup_animateLayoutChanges:
                    boolean animateLayoutChanges = a.getBoolean(attr, false);
                    if (animateLayoutChanges) {
                        setLayoutTransition(new LayoutTransition());
                    }
                    break;

同樣地者铜,我們也可以在代碼中通過設(shè)置LayoutTransition的方式來設(shè)置布局動(dòng)畫块仆,并且LayoutTransition的動(dòng)畫效果可以自定義。從官方文檔中可以看到王暗,LayoutTransition的動(dòng)畫分為四種情景:

  • APPEARING -View出現(xiàn)在布局中的動(dòng)畫標(biāo)志。

  • CHANGE_APPEARING -由于新View出現(xiàn)在布局中而造成其他View改變的動(dòng)畫庄敛。

  • DISAPPEARING - View消失在布局中時(shí)的動(dòng)畫標(biāo)志俗壹。

  • CHANGE_DISAPPEARING - 由于View消失在布局中而造成其他View改變的動(dòng)畫。

    ?

其設(shè)置方法如下:

transition.setAnimator(LayoutTransition.APPEARING,appearingAnim);
transition.setAnimator(LayoutTransition.DISAPPEARING,disappearingAnim);
transition.setAnimator(LayoutTransition.CHANGE_APPEARING,changingAppearingAnim);
transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,changingDisappearingAnim);
//上面的參數(shù)都是普通的ObjectAnimator或者ValueAnimator藻烤。

關(guān)于幀動(dòng)畫

相對(duì)上面兩種動(dòng)畫來說绷雏,幀動(dòng)畫真的不能再簡(jiǎn)單了。其動(dòng)畫實(shí)現(xiàn)原理不同于上面的View局部更新重繪怖亭,而是簡(jiǎn)單粗暴地一幀幀切換已有的圖片涎显,它的XML文件直接放在res/drawable文件夾下,結(jié)構(gòu)如:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot=["true" | "false"] > //只播放一次或者循環(huán)播放
    <item
        android:drawable="@[package:]drawable/drawable_resource_name" //準(zhǔn)備的圖片
        android:duration="integer" /> //該幀播放時(shí)長(zhǎng)
    ...
</animation-list>

在Java中使用時(shí)也就幾行代碼:

ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setBackgroundResource(R.drawable.anim);

animation = (AnimationDrawable) iv.getBackground();
rocketAnimation.start();

就這么簡(jiǎn)單兴猩,但是需要注意的是期吓,不能在onCreate中調(diào)用start()方法,官方解釋是此時(shí)AnimationDrawable對(duì)象還未加載到窗口上倾芝,故推薦有這個(gè)需求是通過在onWindowFocusChanged()中開始動(dòng)畫讨勤,此時(shí)表示Android已經(jīng)將焦點(diǎn)聚集在窗口上,即動(dòng)畫已經(jīng)加載完畢晨另。

最后

各種翻文檔后終于是搞定了這篇其實(shí)并沒有多高深的筆記潭千,里面有些東西被省略了,比如動(dòng)畫狀態(tài)的監(jiān)聽借尿,不過日常大概也不太會(huì)被這種看字面就能理解的東西難住刨晴。還有挺重要的一點(diǎn)是layoutAnimation和Activity Fragment等整體組件切換的動(dòng)畫,某些是5.0以后的效果路翻,以后大概會(huì)補(bǔ)上狈癞。總之以后寫些小動(dòng)畫但想不起來屬性時(shí)終于能告別百度和忍受那些糟糕的界面了茂契,開心亿驾。

如果上面的內(nèi)容有任何錯(cuò)誤或不足,歡迎各種交流指導(dǎo)账嚎,鞠躬莫瞬。
個(gè)人Github主頁(yè):Lazxy

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末儡蔓,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子疼邀,更是在濱河造成了極大的恐慌喂江,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旁振,死亡現(xiàn)場(chǎng)離奇詭異获询,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)拐袜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門吉嚣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蹬铺,你說我怎么就攤上這事尝哆。” “怎么了甜攀?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵秋泄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我规阀,道長(zhǎng)恒序,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任谁撼,我火速辦了婚禮歧胁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘厉碟。我一直安慰自己与帆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布墨榄。 她就那樣靜靜地躺著玄糟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪袄秩。 梳的紋絲不亂的頭發(fā)上阵翎,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音之剧,去河邊找鬼郭卫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛背稼,可吹牛的內(nèi)容都是我干的贰军。 我是一名探鬼主播,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼词疼!你這毒婦竟也來了俯树?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤贰盗,失蹤者是張志新(化名)和其女友劉穎许饿,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舵盈,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡陋率,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了秽晚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓦糟。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖赴蝇,靈堂內(nèi)的尸體忽然破棺而出菩浙,到底是詐尸還是另有隱情,我是刑警寧澤扯再,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站址遇,受9級(jí)特大地震影響熄阻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜倔约,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一秃殉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浸剩,春花似錦钾军、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至重罪,卻和暖如春樱哼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背剿配。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工搅幅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人呼胚。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓茄唐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蝇更。 傳聞我的和親對(duì)象是個(gè)殘疾皇子沪编,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

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