Airbnb最近開源了一個(gè)名叫Lottie的動(dòng)畫庫(kù),它能夠同時(shí)支持iOS,Android與ReactNative的開發(fā).此消息一出,還在苦于探索自定義控件各種炫酷特效的我,興奮地就像發(fā)現(xiàn)的新大陸一般.可以說(shuō),Lottie的出現(xiàn),將極大地解放Android/iOS工程師于無(wú)盡的編寫原生自定義動(dòng)畫的工作中.
當(dāng)我們的項(xiàng)目中用GIF實(shí)現(xiàn)一些復(fù)雜的視覺效果的時(shí)候,會(huì)遇到許多的問(wèn)題.比如,GIF的文件過(guò)于龐大,并且對(duì)于不同分辨率設(shè)備的適配存在不便,并且Gif格式的色深問(wèn)題是一個(gè)死穴.
比如下面這幾個(gè)動(dòng)畫效果:

還有這些:

怎么樣?這些可不是簡(jiǎn)單的移動(dòng)、縮放、旋轉(zhuǎn)就搞得定的,可能有些人思考了之后大概有以下實(shí)現(xiàn)思路:
使用 Gif,這種方式當(dāng)然可行,但是使用 Gif 占用空間較大,而且需要為各種屏幕尺寸、分辨率做適配,因?yàn)?Android 沒有提供原生 Gif 的 api 支持,所以這種方案還會(huì)遇到兼容性問(wèn)題;
使用幀動(dòng)畫,這種方式還不如使用 Gif,一般來(lái)說(shuō)使用幀動(dòng)畫占用空間比 Gif 還要大的多,而且一樣要做多屏幕分辨率的適配,不過(guò)不會(huì)遇到兼容性問(wèn)題;
使用視頻,這種方式當(dāng)然可以,但是一般來(lái)說(shuō)宣傳片才用的上視頻,一般的動(dòng)畫遠(yuǎn)不需要用視頻才能實(shí)現(xiàn)的,未免有些大材小用了,而且占用空間依然很大。
就沒有更好的實(shí)現(xiàn)方式了么?
當(dāng)然有,Android 5.x 之后提供了對(duì) SVG 的支持,通過(guò) VectorDrawable、AnimatedVectorDrawable 的結(jié)合可以實(shí)現(xiàn)一些稍微復(fù)雜的動(dòng)畫,兼容性是一個(gè)問(wèn)題,不過(guò)整個(gè)實(shí)現(xiàn)流程非常麻煩,每次全新實(shí)現(xiàn)一個(gè)動(dòng)畫都得重頭來(lái)過(guò),最最關(guān)鍵的是,如果一個(gè)公司下的 App,iOS 也要實(shí)現(xiàn)一套一樣的動(dòng)畫,資源的占用就顯得過(guò)大了。
而 Airbnb 開源的這個(gè)項(xiàng)目完美的解決以上難題,我們來(lái)看下整個(gè)流程是什么樣的。
假設(shè)我們要做一個(gè)引導(dǎo)頁(yè)面的歡迎動(dòng)畫,這個(gè)一般設(shè)計(jì)師會(huì)用 Adobe 旗下的 After Effects (簡(jiǎn)稱 AE)來(lái)做個(gè)動(dòng)畫出來(lái),設(shè)計(jì)師用 AE 做個(gè)動(dòng)畫比工程師用代碼去實(shí)現(xiàn)一個(gè)動(dòng)畫要快的多的多,調(diào)整起來(lái)也很方便,之后 AE 上有一款插件叫做 Bodymovin,這個(gè)插件也比較屌,可以直接根據(jù) AE 上的動(dòng)畫文件導(dǎo)出 json 文件,這個(gè) json 文件描述了該動(dòng)畫的一些關(guān)鍵點(diǎn)的坐標(biāo)以及運(yùn)動(dòng)軌跡,之后我們?cè)陧?xiàng)目中引用 Lottie 開源庫(kù),在布局文件中簡(jiǎn)單的加上這么幾句引用就完美的實(shí)現(xiàn)了。

如上圖所示,通過(guò)安裝在AE上的一款名叫bodymovin的插件,能夠?qū)E中的動(dòng)畫工程文件轉(zhuǎn)換成通用的json格式描述文件,bodymovin插件本身是用于在網(wǎng)頁(yè)上呈現(xiàn)各種AE效果的一個(gè)開源庫(kù),lottie做的事情就是實(shí)現(xiàn)了一個(gè)能夠在不同移動(dòng)端平臺(tái)上呈現(xiàn)AE動(dòng)畫的方式.從而達(dá)到動(dòng)畫文件的一次繪制、一次轉(zhuǎn)換、隨處可用的效果. 當(dāng)然,就如java一次編譯,隨處運(yùn)行一樣,lottie本身這個(gè)動(dòng)畫播放庫(kù)并不是跨平臺(tái)的.
值得一提的是,我們的 hello-world.json 文件只需要放在 app/src/main/assets 目錄下就 ok 了。
當(dāng)然,還有更多的用法,比如給動(dòng)畫添加事件,比如描述動(dòng)畫的 json 文件可以遠(yuǎn)程更新下載到本地,這樣就可以不動(dòng)聲色的定期更新你的動(dòng)畫了。
有了這個(gè)庫(kù),我們可以充分發(fā)揮我們的想象力,很簡(jiǎn)單方便的就實(shí)現(xiàn)了一套很酷炫的動(dòng)畫,最重要的是,這個(gè)庫(kù)是跨平臺(tái)的,支持 Android、iOS 以及 ReactNative,共用一套 json 動(dòng)畫描述文件。
其實(shí) Facebook 前段時(shí)間開源了一個(gè)類似的庫(kù)叫做 Keyframes,也是跨平臺(tái)的,但是 Littie 比 Keyframes 支持的特性更多,而且據(jù) Airbnb 官方博客介紹,以后對(duì)讓這個(gè)庫(kù)支持更多的特性與功能,不得不說(shuō),真乃良心!
說(shuō)了那么多,下面來(lái)詳細(xì)說(shuō)說(shuō)怎樣使用這個(gè)碉堡的庫(kù).首先聲明,以下涉及到的軟件可能包含破解版,如果你資金充裕,請(qǐng)支持正版. 以下使用方式與軟件在2017年2月6日都有效.
Adobe是個(gè)好公司,做了很多牛逼的軟件,但是無(wú)一例外都被國(guó)人破解了.本例使用的是最新版的AE CC 2017.

可用下載地址 http://www.dayanzai.me/after-effects-cc-2014.html
CDN 分流地址 http://trojx-me.oss-cn-hangzhou.aliyuncs.com/AE%202017%5BWwW.DaYanZai.Me%5D.rar
感謝作者提供軟件.注意此版本只適用于WIN 64位系統(tǒng),筆者在 Win7 64 位 環(huán)境下能夠正常安裝并使用.安裝過(guò)程中按照內(nèi)置說(shuō)明安裝即可.
想了解此插件可以參看該插件的GitHub頁(yè)面 下載bodymovin.zxp插件包
此文件位于工程中的/build/extension/目錄下,如果外網(wǎng)速度慢可以從這里可以下載該插件的最新版本.
項(xiàng)目說(shuō)明中給出了為AE安裝插件的三種方式:
1.通過(guò)第三方軟件ZXP Installer安裝;2.手動(dòng)安裝;3.使用Adobe官方插件安裝器安裝.使用Adobe官方插件安裝器安裝
這三種筆者都試過(guò),最后得出只有第二種(也是看起來(lái)最繁瑣的)有效.這里詳細(xì)說(shuō)明一下第二種方法:
先關(guān)閉AE;用WinRAR或類似軟件打開bodymovin.zxp文件,并將解壓后的文件夾直接復(fù)制到C:/PRogram Files (x86)/Common Files/Adobe/CEP/extensions 或者是C:/AppData/Roaming/Adobe/CEP/extensions下,對(duì)于MAC機(jī)器路徑是/Library/application/ Support/Adobe/CEP/extensions/bodymovin
修改注冊(cè)表.對(duì)于Windows,打開注冊(cè)表修改器,找到HKEY_CURRENT_USER/Software/Adobe/CSXS.6,并在此路徑下添加一個(gè)名為PlayerDebugMode的KEY, 并賦值為1;對(duì)于MAC,打開文件~/Library/Preferences/com.adobe.CSXS.6.plist并在末尾添加一行,鍵為PlayerDebugMode,值為1.設(shè)置AE 無(wú)論以何種方式安裝bodymovin插件,都需要在AE的編輯->首選項(xiàng)->常規(guī)中勾選允許腳本寫入文件和訪問(wèn)網(wǎng)絡(luò)(默認(rèn)不開啟) 
由于筆者目前不會(huì)使用AE(廢話,軟件都是剛裝的),這里我們打開一個(gè)現(xiàn)有的工程文件. 從這里可以找到一些Lottie中演示過(guò)的動(dòng)畫的AE源文件,下載到本地后在AE中打開即可.這里我們選用EmptyState.aep這個(gè)實(shí)例工程,稍作修改:

如果上文的bodymovin插件安裝成功的話,在AE中的窗口->拓展中是能夠找到它的.

在插件窗口中選擇json數(shù)據(jù)文件導(dǎo)出的路徑,點(diǎn)擊Render按鈕即可渲染工程并導(dǎo)出.

原始工程動(dòng)畫效果:

原始工程導(dǎo)出的json文件:http://cdn.trojx.me/blog_raw/lottie_data_origin.json
修改后工程動(dòng)畫效果:

修改后工程導(dǎo)出的json文件:http://cdn.trojx.me/blog_raw/lottie_data_edit.json
終于說(shuō)到主角了,然而關(guān)于它的使用方式卻是相對(duì)簡(jiǎn)單的.Lottie的引入與使用就如其他庫(kù)一樣,這里以Android平臺(tái)的使用為例.
在項(xiàng)目的build.gradle文件中加入:
dependencies { compile 'com.airbnb.android:lottie:1.0.1' ... }Lottie支持Jellybean (API 16)及以上的系統(tǒng),最簡(jiǎn)單的使用方式是直接在布局文件中添加:
<com.airbnb.lottie.LottieAnimationView android:id="@+id/animation_view" android:layout_width="wrap_content" android:layout_height="wrap_content" app:lottie_fileName="hello-world.json" app:lottie_loop="true" app:lottie_autoPlay="true" />或者,你也可以通過(guò)代碼的方式添加.比如從位于app/src/main/assets路徑下的json文件中導(dǎo)入動(dòng)畫數(shù)據(jù):
LottieAnimationView animationView = (LottieAnimationView) findViewById(R.id.animation_view);animationView.setAnimation("hello-world.json");animationView.loop(true);這方法將在后臺(tái)線程異步加載數(shù)據(jù)文件,并在加載完成后開始渲染顯示動(dòng)畫. 如果你想復(fù)用加載的動(dòng)畫,例如下一個(gè)ListView中每一項(xiàng)都需要顯示這個(gè)動(dòng)畫,那么你可以這么做:
LottieAnimationView animationView = (LottieAnimationView) findViewById(R.id.animation_view); ... LottieComposition composition = LottieComposition.fromJson(getResources(), jsonObject, (composition) -> { animationView.setComposition(composition); animationView.playAnimation(); });你還可以通過(guò)API控制動(dòng)畫,并且設(shè)置一些監(jiān)聽:
animationView.addAnimatorUpdateListener((animation) -> { // Do something. }); animationView.playAnimation(); ... if (animationView.isAnimating()) { // Do something. } ... animationView.setProgress(0.5f); ... // 自定義速度與時(shí)長(zhǎng) ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f) .setDuration(500); animator.addUpdateListener(animation -> { animationView.setProgress(animation.getAnimatedValue()); }); animator.start(); ... animationView.cancelAnimation();在使用遮罩的情況下,LottieAnimationView 使用 LottieDrawable來(lái)渲染動(dòng)畫.如果需要的話,你可以直接使用drawable形式:
LottieDrawable drawable = new LottieDrawable(); LottieComposition.fromAssetFileName(getContext(), "hello-world.json", (composition) -> { drawable.setComposition(composition); });如果你需要頻發(fā)使用某一個(gè)動(dòng)畫,可以使用LottieAnimationView內(nèi)置的一個(gè)緩存策略: LottieAnimationView.setAnimation(String, CacheStrategy) 其中CacheStrategy的值可以是Strong,Weak或者None,它們用來(lái)決定LottieAnimationView對(duì)已經(jīng)加載并轉(zhuǎn)換好的動(dòng)畫持有怎樣形式的引用(強(qiáng)引用/弱引用).
lottie在iOS中的使用介紹可以參看陳董DON的文章
分享一個(gè)能夠在瀏覽器中預(yù)覽json動(dòng)畫數(shù)據(jù)的網(wǎng)站
Lottie官方給的Android Demo安裝包使用它能夠查看示例動(dòng)畫,并能夠載入并播放來(lái)自本地存儲(chǔ)或網(wǎng)絡(luò)的json動(dòng)畫數(shù)據(jù).
好了,先寫到這里,我去研究AE去了~后續(xù)應(yīng)該會(huì)補(bǔ)上一個(gè)使用Lottie的Android Demo. 原文地址 http://www.trojx.me/2017/02/06/android-lottie-library/
本文主要轉(zhuǎn)自簡(jiǎn)書作者:Trojx 參考文章:這個(gè)項(xiàng)目碉堡了
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注