我們是如何實現漂亮動畫的-列車飛馳的載入動畫

發表於2016-10-22

上週,我們把Captain Train  app更名為了Trainline。這意味著我們必須改變顏色,圖示,空白狀態以及動畫等以匹配我們的新商標。

在建立新的載入動畫的時候我們遇到了一些問題。因此我覺得這篇部落格可能對開發者夥伴們有點用。實際上,我將嘗試解釋一下我們是如何設計與實現這個動畫的。

劇透:完全是由裝置渲染,無視訊,無gif,只有普通的View和向量動畫。

背景

在app更名之前,在載入搜尋結果時我們顯示的動畫是這樣的:

我們是如何實現漂亮動畫的-列車飛馳的載入動畫

 

這非常簡單,就在app釋出之前不到3小時內我們就完成了。實際上我們只使用了由三個drawable組成的animation-list drawable就完成了。

對於Trainline,我們想要更好的效果。我們的設計師建立了一個漂亮的設計圖。我們的挑戰就是實現它。這裡是我們最終得到的效果:

我們是如何實現漂亮動畫的-列車飛馳的載入動畫

現在來看看我們是如何建立的。

實現

在安卓上有幾種實現動畫的技術。首先要指明的是我希望這個動畫能在 Ice Cream Sandwich (4.0) 上執行,這是我們的minSdk。

讓我們來看看幾種可能的方式:

使用GIF。在web開發中這可能是一個很好的方法,但是安卓並不真正支援GIF。我也並不想為此而專門引入一個新的library。況且,我還必須處理不同的解析度,這對於我們的APK來說是個負擔。

使用video。我不想使用MediaPlay之類的東西。理由還是解析度和加重apk。

使用AnimatedVectorDrawable。考慮到最近已經向後相容,這個方法值得考慮。它很棒,但是會帶來很多XML檔案。而且這個過程也很難在設計師與開發者之間交流,因為設計師很難建立AnimatedVectorDrawable。而且我也不敢保證在低端裝置上能流暢執行。

使用檢視動畫。對於設計師和開發者來說這都比較簡單,只有標準的VectorDrawable。檢視動畫被安卓framework很好的處理了,在過度繪製和效能上都有優化。

設計

越遠越慢

第一步就是設計視察動畫,給人以速度和移動的感覺。我需要把原始影象分解成幾個layer(層)並把它們顯示在ImageView中:

095012ee-0

然後,規則很簡單:“越遠越慢”。比如,風顯然要比地平線移動得快。

一個layer動畫的規則也很簡單,每個layer都是一樣的:讓layer從右到左移動,從視窗的一邊開始,到另一邊結束。重複模式為無限迴圈。layer越遠,動畫的duration(持續時間)越長。讓我們來看一看程式碼示例:

正如你看到的,這非常簡單,這個例子只有X上的動畫,但是某些layer(列車和鳥)可能需要Y上的動畫。

另一個重要的細節就是為了減少記憶體的佔用,每個layer只包裹它的內容,這樣Android只會繪製最小的部分。

 

我們是如何實現漂亮動畫的-列車飛馳的載入動畫

你可以看到動畫中鐵軌是唯一沒有移動的layer。

目前我們並不支援RTL,如果哪天支援的話,改變動畫的方向會很簡單。

Magic disappearance

既然動畫是無限迴圈的,我必須讓layer到達兩邊的時候有個漸進的淡入淡出效果。一旦鳥到達了左邊沿,它必須同時從右邊沿進入。這裡我使用了一個小技巧:用兩個半透明的drawable作為背景。原理如下圖:

0950125395-2

火車自然的移動

對於火車的實現我最開始只是上下移動1dp。當我跟我們的設計師說的時候,他建議我試下實現比這更自然的效果。畢竟火車不是這樣震動的。

我想建立一個遵循我自定義路徑的interpolator:

09501245x-4

最佳方式就是使用PathInterpolator,這個interpolator在開發者中間可能是最不知名的,但是我覺得它更強大,尤其是現在可以使用PathInterpolatorCompat做到向前相容了以後。

讓我們來看看程式碼:

其實沒有啥神祕的。要注意的是,我應該使用quadTo替代ineTo去改進這個interpolation,那樣會更流暢。還要注意的是動畫的重複模式我使用了反向,這樣可以變得連貫。

讓鳥飛起來

這屬於錦上添花的部分。讓我們來看看我是如何做到的。

我說過AnimatedVectorDrawable很棒是吧?剛好它是這個問題的最佳解決方案。第一步是匯入你的VectorDrawable:

pathData的值是翅膀在上時的vector。

然後,你需要一個animator讓翅膀上下襬動。最關鍵的點是讓兩個path data的點具有相同數目。

valueFrom的值是翅膀在上時的向量,valueTo則是翅膀在下時的向量。

0950121e5-6

最後我們使用AnimatedVectorDrawable把VectorDrawable和animator連繫起來:

就如你看到的那樣,這是一個演示了AnimatedVectorDrawables強大之處的基本例子。的確對動畫產生了不小的潤色效果。

總結

作為總結,我想說使用者的反饋是很重要的!你總是需要別人來檢測你的設計是否有意義、漂亮、自然。

對於我而言,如果沒有Enrico的視覺設計,我是無法完成的,也感謝Cyril 和 Thibaut 的反饋和檢驗。

相關文章