Android 動(dòng)畫之kotlin

屬性動(dòng)畫

簡(jiǎn)述

在手機(jī)上去實(shí)現(xiàn)一些動(dòng)畫效果算是件比較炫酷的事情鸣戴,因此Android系統(tǒng)在一開始的時(shí)候就給我們提供了兩種實(shí)現(xiàn)動(dòng)畫效果的方式迹辐,逐幀動(dòng)畫(frame-by-frame animation)和補(bǔ)間動(dòng)畫(tweened animation)。逐幀動(dòng)畫的工作原理很簡(jiǎn)單横蜒,其實(shí)就是將一個(gè)完整的動(dòng)畫拆分成一張張單獨(dú)的圖片胳蛮,然后再將它們連貫起來進(jìn)行播放,類似于動(dòng)畫片的工作原理丛晌。補(bǔ)間動(dòng)畫則是可以對(duì)View進(jìn)行一系列的動(dòng)畫操作仅炊,包括淡入淡出、縮放澎蛛、平移抚垄、旋轉(zhuǎn)四種。
然而自Android 3.0版本開始谋逻,系統(tǒng)給我們提供了一種全新的動(dòng)畫模式呆馁,屬性動(dòng)畫(property animation),它的功能非常強(qiáng)大毁兆,彌補(bǔ)了之前補(bǔ)間動(dòng)畫的一些缺陷浙滤,幾乎是可以完全替代掉補(bǔ)間動(dòng)畫了。對(duì)于逐幀動(dòng)畫和補(bǔ)間動(dòng)畫的用法气堕,我不想再多講纺腊,它們的技術(shù)已經(jīng)比較老了畔咧,而且網(wǎng)上資料也非常多,那么今天我們這篇文章的主題就是對(duì)Android屬性動(dòng)畫進(jìn)行一次完全解析揖膜。
為什么要引入屬性動(dòng)畫誓沸?
Android之前的補(bǔ)間動(dòng)畫機(jī)制其實(shí)還算是比較健全的,在android.view.animation包下面有好多的類可以供我們操作壹粟,來完成一系列的動(dòng)畫效果拜隧,比如說對(duì)View進(jìn)行移動(dòng)、縮放趁仙、旋轉(zhuǎn)和淡入淡出洪添,并且我們還可以借助AnimationSet來將這些動(dòng)畫效果組合起來使用,除此之外還可以通過配置Interpolator來控制動(dòng)畫的播放速度等等等等幸撕。那么這里大家可能要產(chǎn)生疑問了薇组,既然之前的動(dòng)畫機(jī)制已經(jīng)這么健全了,為什么還要引入屬性動(dòng)畫呢坐儿?
其實(shí)上面所謂的健全都是相對(duì)的,如果你的需求中只需要對(duì)View進(jìn)行移動(dòng)宋光、縮放貌矿、旋轉(zhuǎn)和淡入淡出操作,那么補(bǔ)間動(dòng)畫確實(shí)已經(jīng)足夠健全了罪佳。但是很顯然逛漫,這些功能是不足以覆蓋所有的場(chǎng)景的,一旦我們的需求超出了移動(dòng)赘艳、縮放酌毡、旋轉(zhuǎn)和淡入淡出這四種對(duì)View的操作,那么補(bǔ)間動(dòng)畫就不能再幫我們忙了蕾管,也就是說它在功能和可擴(kuò)展方面都有相當(dāng)大的局限性枷踏,那么下面我們就來看看補(bǔ)間動(dòng)畫所不能勝任的場(chǎng)景。
注意上面我在介紹補(bǔ)間動(dòng)畫的時(shí)候都有使用“對(duì)View進(jìn)行操作”這樣的描述掰曾,沒錯(cuò)旭蠕,補(bǔ)間動(dòng)畫是只能夠作用在View上的。也就是說旷坦,我們可以對(duì)一個(gè)Button掏熬、TextView、甚至是LinearLayout秒梅、或者其它任何繼承自View的組件進(jìn)行動(dòng)畫操作旗芬,但是如果我們想要對(duì)一個(gè)非View的對(duì)象進(jìn)行動(dòng)畫操作,抱歉捆蜀,補(bǔ)間動(dòng)畫就幫不上忙了疮丛×纠牛可能有的朋友會(huì)感到不能理解,我怎么會(huì)需要對(duì)一個(gè)非View的對(duì)象進(jìn)行動(dòng)畫操作呢这刷?這里我舉一個(gè)簡(jiǎn)單的例子婉烟,比如說我們有一個(gè)自定義的View,在這個(gè)View當(dāng)中有一個(gè)Point對(duì)象用于管理坐標(biāo)暇屋,然后在onDraw()方法當(dāng)中就是根據(jù)這個(gè)Point對(duì)象的坐標(biāo)值來進(jìn)行繪制的似袁。也就是說,如果我們可以對(duì)Point對(duì)象進(jìn)行動(dòng)畫操作咐刨,那么整個(gè)自定義View的動(dòng)畫效果就有了昙衅。顯然,補(bǔ)間動(dòng)畫是不具備這個(gè)功能的定鸟,這是它的第一個(gè)缺陷而涉。
然后補(bǔ)間動(dòng)畫還有一個(gè)缺陷,就是它只能夠?qū)崿F(xiàn)移動(dòng)联予、縮放啼县、旋轉(zhuǎn)和淡入淡出這四種動(dòng)畫操作,那如果我們希望可以對(duì)View的背景色進(jìn)行動(dòng)態(tài)地改變呢沸久?很遺憾季眷,我們只能靠自己去實(shí)現(xiàn)了。說白了卷胯,之前的補(bǔ)間動(dòng)畫機(jī)制就是使用硬編碼的方式來完成的子刮,功能限定死就是這些,基本上沒有任何擴(kuò)展性可言窑睁。
最后挺峡,補(bǔ)間動(dòng)畫還有一個(gè)致命的缺陷,就是它只是改變了View的顯示效果而已担钮,而不會(huì)真正去改變View的屬性橱赠。什么意思呢?比如說裳朋,現(xiàn)在屏幕的左上角有一個(gè)按鈕病线,然后我們通過補(bǔ)間動(dòng)畫將它移動(dòng)到了屏幕的右下角,現(xiàn)在你可以去嘗試點(diǎn)擊一下這個(gè)按鈕鲤嫡,點(diǎn)擊事件是絕對(duì)不會(huì)觸發(fā)的送挑,因?yàn)閷?shí)際上這個(gè)按鈕還是停留在屏幕的左上角,只不過補(bǔ)間動(dòng)畫將這個(gè)按鈕繪制到了屏幕的右下角而已暖眼。
也正是因?yàn)檫@些原因惕耕,Android開發(fā)團(tuán)隊(duì)決定在3.0版本當(dāng)中引入屬性動(dòng)畫這個(gè)功能,那么屬性動(dòng)畫是不是就把上述的問題全部解決掉了诫肠?下面我們就來一起看一看司澎。
新引入的屬性動(dòng)畫機(jī)制已經(jīng)不再是針對(duì)于View來設(shè)計(jì)的了欺缘,也不限定于只能實(shí)現(xiàn)移動(dòng)、縮放挤安、旋轉(zhuǎn)和淡入淡出這幾種動(dòng)畫操作谚殊,同時(shí)也不再只是一種視覺上的動(dòng)畫效果了。它實(shí)際上是一種不斷地對(duì)值進(jìn)行操作的機(jī)制蛤铜,并將值賦值到指定對(duì)象的指定屬性上嫩絮,可以是任意對(duì)象的任意屬性。所以我們?nèi)匀豢梢詫⒁粋€(gè)View進(jìn)行移動(dòng)或者縮放围肥,但同時(shí)也可以對(duì)自定義View中的Point對(duì)象進(jìn)行動(dòng)畫操作了剿干。我們只需要告訴系統(tǒng)動(dòng)畫的運(yùn)行時(shí)長(zhǎng),需要執(zhí)行哪種類型的動(dòng)畫穆刻,以及動(dòng)畫的初始值和結(jié)束值置尔,剩下的工作就可以全部交給系統(tǒng)去完成了。
既然屬性動(dòng)畫的實(shí)現(xiàn)機(jī)制是通過對(duì)目標(biāo)對(duì)象進(jìn)行賦值并修改其屬性來實(shí)現(xiàn)的氢伟,那么之前所說的按鈕顯示的問題也就不復(fù)存在了榜轿,如果我們通過屬性動(dòng)畫來移動(dòng)一個(gè)按鈕,那么這個(gè)按鈕就是真正的移動(dòng)了腐芍,而不再是僅僅在另外一個(gè)位置繪制了而已差导。
好了,介紹了這么多猪勇,相信大家已經(jīng)對(duì)屬性動(dòng)畫有了一個(gè)最基本的認(rèn)識(shí)了,下面我們就來開始學(xué)習(xí)一下屬性動(dòng)畫的用法颠蕴。

核心類

  • ValueAnimator:該類是Animator的子類泣刹,實(shí)現(xiàn)了動(dòng)畫的整個(gè)處理邏輯也是屬性動(dòng)畫的核心類
  • ObjectAnimator:對(duì)象屬性動(dòng)畫的操作類,繼承自ValueAnimator,通過該類使用動(dòng)畫的形式操作對(duì)象的屬性
  • TimeInterpolator:時(shí)間插值器犀被,他的作用是根據(jù)時(shí)間流逝的百分比來計(jì)算出當(dāng)前屬性值改變的百分比椅您,系統(tǒng)預(yù)置的有線性插值器(LinearInterpolator)、加速插值器(AccelerateDeceleratenterpolator)和減速插值器(DecelerateInterpolator)等寡键。
  • TypeEvaluator:TypeEvaluator的中文為類型估值算法掀泳,他的作用是根據(jù)當(dāng)前屬性改變的百分比來計(jì)算改變后的屬性值,系統(tǒng)預(yù)支的有針對(duì)整形屬性(IntEvaluator)西轩、針對(duì)浮點(diǎn)型(FloatEvaluator)和針對(duì)Color屬性(ArgbEvaluator)
  • Property:屬性對(duì)象员舵,主要是定義了屬性的set和get方法。
  • PropertyValuesHolder: PropertyValuesHolder是持有目標(biāo)屬性Property藕畔、setter和getter方法以及關(guān)鍵幀的集合
  • KeyframeSet:儲(chǔ)存一個(gè)動(dòng)畫的關(guān)鍵幀集合马僻。
  • AnimotionProxy:再3.0以下使用View的屬性動(dòng)畫的輔助類

基本使用

這是一個(gè)讓textview點(diǎn)擊向下移動(dòng)的demo
效果展示

2017-12-08 16.42.48.gif
xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="transformation.numberutils.wushaocong.manimotor.MainActivity">
    
    <TextView
        android:text="移動(dòng)"
        android:textSize="20sp"
        android:layout_centerInParent="true"
        android:id="@+id/mtext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>
kotlin:
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var y = 100f
        mtext.setOnClickListener { v ->
            ObjectAnimator.ofFloat(v, "translationY", y).start()
            y+=100f
        }
    }
}

這是一個(gè)將textview的背景3秒鐘從0xF000000變?yōu)?xF00ffff 無限播放且有反轉(zhuǎn)效果


2017-12-09 10.45.20.gif

直接把剛才的代碼修改為

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var y = 100f
        mtext.setOnClickListener { v ->
            val colorAnimator = ObjectAnimator.ofInt(v,"backgroundColor",0xF000000,0xF00ffff)
            //設(shè)置動(dòng)畫時(shí)間
            colorAnimator.setDuration(3000)
            //設(shè)置插值器
            colorAnimator.setEvaluator(ArgbEvaluator())
            //設(shè)置播放次數(shù)為無限
            colorAnimator.repeatCount = ValueAnimator.INFINITE
            //播放完成之后反轉(zhuǎn)
            colorAnimator.repeatMode = ValueAnimator.REVERSE
            colorAnimator.start()
        }
    }
}

  • 最后再來一個(gè)終極的動(dòng)畫組合


    2017-12-08 17.25.36.gif

將代碼修改為:


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var y = 100f
        mtext.setOnClickListener { v ->
            var animators = listOf<ObjectAnimator>(
                    ObjectAnimator.ofFloat(v,"rotationX",0f,360f),
                    ObjectAnimator.ofFloat(v,"rotationY",0f,180f),
                    ObjectAnimator.ofFloat(v,"rotation",0f,-90f),
                    ObjectAnimator.ofFloat(v,"translationX",0f,90f),
                    ObjectAnimator.ofFloat(v,"translationY",0f,90f),
                    ObjectAnimator.ofFloat(v,"scaleY",1f,1.5f),
                    ObjectAnimator.ofFloat(v,"scaleX",1f,0.5f),
                    ObjectAnimator.ofFloat(v,"alpha",0f,1f,0.25f,1f)
            )
            val set  = AnimatorSet()
            set.playTogether(animators)
            set.setDuration(6*1000).start()
        }
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市注服,隨后出現(xiàn)的幾起案子韭邓,更是在濱河造成了極大的恐慌措近,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件女淑,死亡現(xiàn)場(chǎng)離奇詭異瞭郑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)鸭你,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門屈张,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人苇本,你說我怎么就攤上這事袜茧。” “怎么了瓣窄?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵笛厦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我俺夕,道長(zhǎng)裳凸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任劝贸,我火速辦了婚禮姨谷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘映九。我一直安慰自己梦湘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布件甥。 她就那樣靜靜地躺著捌议,像睡著了一般。 火紅的嫁衣襯著肌膚如雪引有。 梳的紋絲不亂的頭發(fā)上瓣颅,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音譬正,去河邊找鬼宫补。 笑死,一個(gè)胖子當(dāng)著我的面吹牛曾我,可吹牛的內(nèi)容都是我干的粉怕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼您单,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼斋荞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起虐秦,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤平酿,失蹤者是張志新(化名)和其女友劉穎凤优,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜈彼,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡筑辨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了幸逆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棍辕。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖还绘,靈堂內(nèi)的尸體忽然破棺而出楚昭,到底是詐尸還是另有隱情,我是刑警寧澤拍顷,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布抚太,位于F島的核電站,受9級(jí)特大地震影響昔案,放射性物質(zhì)發(fā)生泄漏尿贫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一踏揣、第九天 我趴在偏房一處隱蔽的房頂上張望庆亡。 院中可真熱鬧,春花似錦捞稿、人聲如沸又谋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)搂根。三九已至,卻和暖如春铃辖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背猪叙。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工娇斩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人穴翩。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓犬第,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親芒帕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子歉嗓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

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

  • 1 背景 不能只分析源碼呀,分析的同時(shí)也要整理歸納基礎(chǔ)知識(shí)背蟆,剛好有人微博私信讓全面說說Android的動(dòng)畫鉴分,所以今...
    未聞椛洺閱讀 2,709評(píng)論 0 10
  • 轉(zhuǎn)載一篇高質(zhì)量博文哮幢,原地址請(qǐng)戳這里轉(zhuǎn)載下來方便今后查看。1 背景不能只分析源碼呀志珍,分析的同時(shí)也要整理歸納基礎(chǔ)知識(shí)橙垢,...
    Elder閱讀 1,942評(píng)論 0 24
  • 對(duì)于android手機(jī)上的動(dòng)畫實(shí)現(xiàn)主要有三種,一種是幀動(dòng)畫伦糯,一種是View動(dòng)畫柜某,以及3.0以上提供的屬性動(dòng)畫,所有...
    查理吃西瓜閱讀 6,524評(píng)論 1 39
  • 其實(shí)每個(gè)人活在這個(gè)地球上都是很不容易的一件事敛纲。有是在想—為什么霧霾是越來越嚴(yán)重呢喂击? 這個(gè)問題其實(shí)不難回答...
    快樂的開始閱讀 309評(píng)論 0 0
  • 寫了很多篇關(guān)于美食的文章翰绊,承認(rèn)自己喜歡寫美食,但是心里總有個(gè)聲音在說想寫小說办铡!可是小說我不會(huì)寫辞做,怎么辦?于是我停了...
    小月半腳閱讀 348評(píng)論 11 10