2018-05-22—屬性動畫(6) 聯合動畫AnimatorSet詳解

最近在看源碼的註釋時候,都在努力地自己翻譯官方的英文文檔(老師推薦方法),確實是有效果的,筆者不跟大家樹新風(tree  new  bee),今天這篇聯合動畫的源碼註釋大多數都是靠自己翻譯的,除了一些個別不認識的生詞意外。這是一個好習慣,推薦給大家,也希望我們大家在Android的道路上越來越強。


到目前爲止,我們現在已經學習了屬性動畫如下知識:

ValueAnimator,ObjectAnimator使用。

PropertyValueHolder,KeyFrame使用

插值器Interpolator,估值器TypeEvaluator使用。

總體上就是已經學了這些東西了。而屬性動畫中有一個類,可以把多個屬性動畫組合成統一的一個動畫效果,沒錯,他就是聯合動畫——AnimatorSet,今天我們主要來詳細介紹一下這個類——AnimatorSet.Builder


AnimatorSet.Builder

10608194-1ea8afdb38c92d79.png

這是對這個類最原始的解釋:按照指定的順序播放動畫對象,可以按順序播放,可也以同時播放。。。。具體更多的大家去看AnimatorSet的源碼註釋就可以。

那我們現在知道,這個類就是爲了將動畫組合而生的,而具體組合出什麼邏輯是我們自己決定的。

在具體介紹AnimatorSet之前,我想先說一下AnimatorSet中的一個內部類——Builder

10608194-e6081d2213ec0f6a.png
Builder註釋

直譯過來:Builder這個類,是用來幫助AnimatorSet將動畫添加到AnimatorSet中,或者是處理各種動畫的依賴關係。

可能這麼說很抽象,我們暫時先這麼理解:

1.Builder用來將動畫加入AnimatorSet中。

2.Builder建立了一種約束關係,讓AnimatorSet中的一系列動畫有先後順序播放。

現在到此爲止,接下來我們會結合AnimatorSet的4中方法來繼續理解Builder的意義:


AnimatorSet的play方法和Builder的with,before,after方法

既然我們要讓許多的屬性動畫聯合在一起,那我們肯定需要有方法把他們放入AnimatorSet中:總體來說,我們放入Animator的方法有如下四種:play(Animator anim),with(Animator anim),before(Animator anim),after(Animator anim)。

其中play是AnimatorSet的方法,其餘三種都是Builder類中的方法。

我們依次說一下這幾個方法:

play:

10608194-c04d2018621e51cd.png

直譯:play方法創建了一個Builder對象,這個對象用於建立動畫之間的約束關係。

play方法告訴這個Builder對象,play中的這個動畫是接下來的所有動畫的依賴。

然後看註釋下面給出的例子:

play(a1).with(a2)    a1和a2同時開始

play(a1).before(a2)   先a1後a2

play(a1).after(a2)  先a2後a1

我們先不用管with,before,after實際的意義,反正我們知道這個play方法中返回了一個Builder對象,接着之後的所有動畫都是和a1聯繫(他得播放順序)。

而且,Builder對象生成的唯一途徑,就是通過AnimatorSet的play方法。


with:

10608194-f18cf50b1fa5ada2.png

意譯:設置一個動畫,和play設置的動畫同時播放,然後返回play創建的Builder對象。

這個方法應該很好理解,就是和play中的動畫同時播放。


before:

10608194-0119b19d2d633cca.png

意譯:在創建這個Builder對象的方法(也就是play方法)的動畫結束時候,啓動這個動畫(before中的動畫)。

所以play(a1).before(a2);是先執行a1,後執行a2,他們是有先後順序的。


after:

10608194-18c15ef133c0ee86.png

意譯:在這個方法(after)中的動畫結束時,執行創建這個Builder對象的方法(play)中的動畫。

所以play(a1).after(a2),是先執行a2,後執行a1。


現在我們知道這四個方法各自的用途了。那我們來做一個簡單的小測試:

我們知道with會和play中的動畫同時啓動,我們看如下代碼:

10608194-ae3c141ea1885b2a.png

很簡單的一個動畫,兩個控件(具體什麼控件大家自己去實現吧),分別給兩個控件動畫,a1延時2秒,聯合動畫延時2秒。我們看看他是如何動作的:

10608194-4dafbc589e2ae827.gif

我們發現他們一共延時了4秒,我們把代碼做一下輕微的改變:

10608194-2c4ea8c27f6920cf.gif

我們發現延時兩秒以後,a2先動作了,然後a1動作了。

其實這個現象很好解釋:

最開始的2秒延時是我們set的啓動延時,2秒後set啓動,然後執行play的動畫,如果play的動畫沒有延時就直接執行,伴隨着with的動畫,如果with的動畫也沒有延時,兩者一起執行,如果with有延時,那麼就延時執行。

相反:如果set延時後執行,play的動畫也有延時,那麼延時等待,當play執行時候,with的動畫也執行。


我舉一個很簡單的例子:

大家都知道賽馬吧:把馬擋在門後面,後面有人拉着。我們的動畫方法就相當於打開門,延時幾秒就相當於人拉着它幾秒,幾秒過後人放手,馬就跑了,這時候下一匹馬的門打開,如果有延時還會被拉住,沒有馬就立刻跑。

無論是play,with,before,after,都是遵循這個規矩的。我們再舉一個例子:

10608194-a736a212b8f412d5.png

還是這段代碼,只是設定a1爲after先執行與a2,a1還是有2秒延時。

10608194-b6f1a465963112e7.gif

set先延時2秒,然後a1延時2秒,a1啓動,a1結束後a2啓動。

關於這四個方法我們就講這麼多。接下來我們看一下Set中的兩個方法:


playSequentially和playTogether方法

其實說白了,這兩個方法就是對上面四種方法的封裝,我們看一下他們的實現:

10608194-a8e88faa26023091.png
playTogether實現

我們先play第一個動畫創建Builder對象,然後從索引1開始到最後一個,全部都with啓動。

10608194-888cb0887852a0e4.png
playSequentially實現

只是多了一個位判斷,如果只有一個就只執行一個動畫;如果多餘1個,就從第一個開始依次執行

看了源碼之後,大家應該已經會用這兩個方法了吧。


好了,關於聯合動畫使用就這麼多了。

發佈了85 篇原創文章 · 獲贊 98 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章