Android屬性動(dòng)畫(一) 初識(shí)基本用法

封面

1.介紹

Android系統(tǒng)為我們提供了三種動(dòng)畫效果的實(shí)現(xiàn)方式:

  • 補(bǔ)間動(dòng)畫(Tween Animation):只能對(duì)View進(jìn)行動(dòng)畫操作,支持移動(dòng)洼畅、旋轉(zhuǎn)吩案、透明、縮放四種效果帝簇,有一定的局限性徘郭。

  • 逐幀動(dòng)畫(Frame Animation):把一個(gè)動(dòng)畫分成多張圖片,然后把這些圖片連貫起來播放丧肴,原理和動(dòng)畫片類似残揉。

  • 屬性動(dòng)畫(Property Animation):通過改變對(duì)象的屬性值來實(shí)現(xiàn)的動(dòng)畫效果,不局限使用在View上芋浮。

由于補(bǔ)間動(dòng)畫的局限性抱环,Android團(tuán)隊(duì)在3.0版本中引入了屬性動(dòng)畫,它的功能相當(dāng)強(qiáng)大纸巷,彌補(bǔ)了補(bǔ)間動(dòng)畫的不足镇草,幾乎可以完全替代補(bǔ)間動(dòng)畫了。

如果你想在自定義控件的某一個(gè)點(diǎn)上使用動(dòng)畫瘤旨,給View設(shè)置一個(gè)平滑的顏色過渡梯啤,或者使用3D旋轉(zhuǎn)動(dòng)畫,那么屬性動(dòng)畫一定是你最佳的選擇存哲,下面就讓我們一起來看看屬性動(dòng)畫的基本用法吧因宇。

2.ValueAnimator

ValueAnimator是整個(gè)屬性動(dòng)畫機(jī)制中最核心的一個(gè)類七婴,因?yàn)閷傩詣?dòng)畫就是通過不斷的改變對(duì)象的屬性值來實(shí)現(xiàn)的動(dòng)畫效果,初始值和結(jié)束值之間的動(dòng)畫過渡就是由ValueAnimator這個(gè)類來完成計(jì)算的察滑。

ValueAnimator的用法還是比較簡(jiǎn)單的本姥,比如想要把一個(gè)值從0平滑的過渡到1,間隔300ms杭棵,就可以這樣寫:

ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
animator.setDuration(300);
animator.start();

三行代碼搞定婚惫,是不是很簡(jiǎn)單,但是這樣運(yùn)行起來是看不出任何效果的魂爪,還需要加上一個(gè)監(jiān)聽器:

ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
animator.setDuration(300);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float currentValue = (float) animation.getAnimatedValue();
        Log.i("onAnimationUpdate", "currentValue:" + currentValue);
    }
});
animator.start();

運(yùn)行一下先舷,看下打印:

ValueAnimator

可以看到ValueAnimator幫我們計(jì)算了從0到1的過渡值滓侍,ofFloat方法是可以傳入多個(gè)參數(shù)的蒋川,比如在1s內(nèi),從0過渡到6撩笆,再過渡到3捺球,然后再過渡到10,就可以這樣寫:

ValueAnimator animator = ValueAnimator.ofFloat(0f, 6f, 3f, 10f);
animator.setDuration(1000);
animator.start();

如果你不想要小數(shù)值過渡的話夕冲,還可以使用ofInt方法氮兵,使用和ofFloat方法相同,ValueAnimator中比較常用的就是ofFloat和oFInt方法了歹鱼,還有一個(gè)ofObject泣栈,我會(huì)在下篇文章中講解。

可以看到上述代碼中弥姻,可以設(shè)置動(dòng)畫的播放時(shí)間南片,除此之外還有一些常見的功能:

// 設(shè)置動(dòng)畫的重復(fù)次數(shù)
// 直接傳入int型數(shù)值,INFINITE代表無限循環(huán)
animator.setRepeatCount(ValueAnimator.INFINITE);

// 設(shè)置動(dòng)畫的重復(fù)模式
// RESTART代表重新播放庭敦,REVERSE代表倒序播放
animator.setRepeatMode(ValueAnimator.RESTART);
animator.setRepeatMode(ValueAnimator.REVERSE);

// 設(shè)置動(dòng)畫的延遲播放時(shí)間
animator.setStartDelay(1000);

3.ObjectAnimator

與ValueAnimator相比ObjectAnimator才是我們最常用到的類疼进,ObjectAnimator繼承于ValueAnimator,其內(nèi)部的動(dòng)畫機(jī)制是依靠ValueAnimator來完成的秧廉,由于是繼承關(guān)系伞广,在ObjectAnimator中也可以使用ValueAnimator中的一些方法,兩者的用法也很類似定血,下面就讓我們來看看ObjectAnimator的一些常見用法赔癌。

移動(dòng)

把一張圖片沿X軸向右移動(dòng)100px,然后向左移動(dòng)回到原位:

// 沿X軸向移動(dòng)100px澜沟,然后向左移動(dòng)回到原位
// 沿Y軸移動(dòng),ofFloat第二個(gè)參數(shù)傳入translationY
ObjectAnimator animator = ObjectAnimator.ofFloat(image, "translationX", 0f, 100f, 0f);
// 動(dòng)畫執(zhí)行時(shí)長(zhǎng)2s峡谊,默認(rèn)300ms
animator.setDuration(2000);
animator.start();
移動(dòng)

3D旋轉(zhuǎn)

把一張圖片垂直旋轉(zhuǎn)360度:

// 垂直旋轉(zhuǎn)360度
// 水平旋轉(zhuǎn)茫虽,ofFloat第二個(gè)參數(shù)傳入rotationX
ObjectAnimator animator = ObjectAnimator.ofFloat(image, "rotationY", 0f, 360f);
animator.setDuration(2000);
animator.start();
3D旋轉(zhuǎn)

透明

把一張圖片的透明度從0調(diào)節(jié)到1:

// 透明度從0到1
ObjectAnimator animator = ObjectAnimator.ofFloat(image, "alpha", 0f, 1f);
animator.setDuration(2000);
animator.start();
透明

縮放

把一張圖片水平縮放0.5倍刊苍,然后恢復(fù):

// 水平縮放0.5倍,然后恢復(fù)
// 垂直縮放濒析,ofFloat第二個(gè)參數(shù)傳入scaleY
ObjectAnimator animator = ObjectAnimator.ofFloat(image, "scaleX", 1f, 0.5f, 1f);
animator.setDuration(2000);
animator.start();
縮放

屬性動(dòng)畫中圖片的移動(dòng)是實(shí)現(xiàn)了圖片真正意義上的移動(dòng)正什,改變位置后可以點(diǎn)擊,與此相比号杏,補(bǔ)間動(dòng)畫只是改變了圖片的顯示效果婴氮,移動(dòng)后不能點(diǎn)擊,這也是屬性動(dòng)畫和補(bǔ)間動(dòng)畫的一個(gè)重要區(qū)別盾致。

ofFloat方法的第二個(gè)參數(shù)可以傳入任意對(duì)象的屬性名主经,ObjectAnimator內(nèi)部的工作原理就是通過在View中查找屬性名對(duì)應(yīng)的get、set方法來設(shè)置對(duì)應(yīng)的屬性值的庭惜。

通俗的來講罩驻,就是假如屬性名是alpha,ObjectAnimator就會(huì)在ImageView中查找getAlpha方法和setAlpha方法护赊,然后進(jìn)行透明度設(shè)置的惠遏。

4.組合動(dòng)畫

組合動(dòng)畫需要借助AnimatorSet這個(gè)類來完成,AnimatorSet提供了play(Animator anim)方法骏啰,傳入Animator對(duì)象之后返回一個(gè)AnimatorSet.Builder實(shí)例节吮,AnimatorSet.Builder中有下面幾個(gè)方法:

  • with(Animator anim):將現(xiàn)有的動(dòng)畫和傳入的動(dòng)畫同時(shí)執(zhí)行。

  • before(Animator anim):將現(xiàn)有的動(dòng)畫在傳入的動(dòng)畫之前執(zhí)行判耕。

  • after(Animator anim):將現(xiàn)有的動(dòng)畫在傳入的動(dòng)畫之后執(zhí)行课锌。

  • after(long delay):將現(xiàn)有的動(dòng)畫延時(shí)執(zhí)行。

舉個(gè)栗子:

// 圖片從屏幕左側(cè)移動(dòng)到右側(cè)祈秕,再回到原位渺贤,同時(shí)透明度從0調(diào)節(jié)到1,然后垂直旋轉(zhuǎn)360度
ObjectAnimator trans = ObjectAnimator.ofFloat(image, "translationX", -100f, 100f, 0f);
ObjectAnimator alpha = ObjectAnimator.ofFloat(image, "alpha", 0f, 1f);
ObjectAnimator rotation = ObjectAnimator.ofFloat(image, "rotationY", 0f, 360f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(trans).with(alpha).before(rotation);
animatorSet.setDuration(5000);
animatorSet.start();
組合動(dòng)畫

5.使用xml編寫動(dòng)畫

在res目錄下創(chuàng)建一個(gè)animator文件夾请毛,然后新建一個(gè)屬性動(dòng)畫的xml文件志鞍,xml中可以使用如下三種標(biāo)簽:

  • animator:對(duì)應(yīng)代碼中的ValueAnimator類。

  • objectAnimator:對(duì)應(yīng)代碼中的ObjectAnimator類方仿。

  • set:對(duì)應(yīng)代碼中的AnimatorSet類固棚。

以上面的組合動(dòng)畫為例,使用xml來編寫下:

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">

    <set android:ordering="together">
        <set android:ordering="sequentially">
            <objectAnimator
                android:duration="2000"
                android:propertyName="translationX"
                android:valueFrom="-100"
                android:valueTo="100"
                android:valueType="floatType" />

            <objectAnimator
                android:duration="2000"
                android:propertyName="translationX"
                android:valueFrom="100"
                android:valueTo="0"
                android:valueType="floatType" />
        </set>

        <objectAnimator
            android:duration="2000"
            android:propertyName="alpha"
            android:valueFrom="0"
            android:valueTo="1"
            android:valueType="floatType" />
    </set>

    <objectAnimator
        android:duration="2000"
        android:propertyName="rotationY"
        android:valueFrom="0"
        android:valueTo="360"
        android:valueType="floatType" />

</set>

ordering屬性可以設(shè)置為sequentially(順序執(zhí)行)仙蚜、together(同時(shí)執(zhí)行)此洲。
在代碼中調(diào)用:

// 圖片從屏幕左側(cè)移動(dòng)到右側(cè),再回到原位委粉,同時(shí)透明度從0調(diào)節(jié)到1呜师,然后垂直旋轉(zhuǎn)360度
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.combine);
animator.setTarget(image);
animator.start();

6.寫在最后

Ok,到這里屬性動(dòng)畫的基本用法就講完了贾节,在下篇文章中我會(huì)寫一些屬性動(dòng)畫的高級(jí)用法汁汗,敬請(qǐng)期待衷畦!

源碼已托管到GitHub上,歡迎Fork知牌,覺得還不錯(cuò)就Start一下吧祈争!

GitHub地址:https://github.com/alidili/PropertyAnimationDemo

歡迎同學(xué)們吐槽評(píng)論,如果你覺得本篇博客對(duì)你有用角寸,那么就留個(gè)言或者點(diǎn)下喜歡吧(^-^)

《Android屬性動(dòng)畫(二) ValueAnimator的實(shí)際應(yīng)用 & 自定義TypeEvaluator》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末菩混,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子扁藕,更是在濱河造成了極大的恐慌沮峡,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纹磺,死亡現(xiàn)場(chǎng)離奇詭異帖烘,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)橄杨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門秘症,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人式矫,你說我怎么就攤上這事乡摹。” “怎么了采转?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵聪廉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我故慈,道長(zhǎng)板熊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任察绷,我火速辦了婚禮干签,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拆撼。我一直安慰自己容劳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布闸度。 她就那樣靜靜地躺著竭贩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪莺禁。 梳的紋絲不亂的頭發(fā)上留量,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼肪获。 笑死寝凌,一個(gè)胖子當(dāng)著我的面吹牛柒傻,可吹牛的內(nèi)容都是我干的孝赫。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼红符,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼青柄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起预侯,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤致开,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后萎馅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體双戳,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年糜芳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了飒货。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡峭竣,死狀恐怖塘辅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情皆撩,我是刑警寧澤扣墩,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站扛吞,受9級(jí)特大地震影響呻惕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜滥比,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一亚脆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧守呜,春花似錦型酥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至玛迄,卻和暖如春由境,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國打工虏杰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留讥蟆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓纺阔,卻偏偏與公主長(zhǎng)得像瘸彤,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子笛钝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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