Android列表動圖展示策略
在最近的時間裡,短視訊流行了起來,隨著這股潮流,一種動圖封面的設計也被很多短視訊app採用:

某音
而在app中,動圖的展示是比較消耗效能的操作,對於這種一頁非常多的動圖在展示時需要做對應的處理,今天我結合自己在專案中處理的經驗分享一下多動圖的處理策略。
圖片載入框架選擇
對於動圖的載入,尤其是webp格式的動圖,Fresco真是不二的選擇,而且fresco本身對記憶體的處理也很棒,本文是基於Fresco 1.0.10版本,如果使用低版本Fresco出現無解的問題時,不妨可以試著升級Fresco版本。
圖片展示的策略
- 只在當前頁展示
我們知道,動圖是由一幀一幀的靜圖組成的,通常來說我們需要這個動圖一直播放,也就是說動圖從載入完成之後會不停的渲染每一幀,拿某音舉例:

首頁
假設下面的“首頁”“、”關注”、“訊息”、“我”4個tab都有動圖,當我們點選其他頁面時,當前頁被隱藏,而根據Fresco的官方文件 ofollow,noindex">Fresco中文官方文件 通常只有當SimpleDrawView被移出螢幕才會停止播放動畫(我在測試中發現通常Activity生命週期級別的也會觸發),所以當tab頁隱藏時動圖依舊在被渲染,所以我們需要控制動圖的停止和播放,只有當前頁展示時,才播放動圖:
Animatable animatable = mSimpleDraweeView.getController().getAnimatable(); if (animatable != null) { animatable.start(); // later animatable.stop(); }
- 只在可見區域展示
當我們做列表動圖的時候,無論控制元件是listview還是recyclerview,資料和item的繫結都會在螢幕外繫結,而此時站在效能優化的角度上,是不需要渲染動圖的;當動圖滑動在列表邊界的時候,是不是說明使用者的焦點已經不在這張圖上了,所以此時可以提前在動圖滑出螢幕外之前停止動圖播放(在專案中我與產品商定動圖播放和停止的邊界值定為圖片的1/2,也就是說圖片滑入螢幕自身長度1/2的時候播放動圖,滑出螢幕自身長度1/2的時候停止播放);當快速滑動的時候也應當停止動圖渲染(平時載入靜圖可能不需要在意,但是在android老手機上載入很多動圖會使得cpu和記憶體大幅度浮動)。
也就是說當列表在做資料繫結的時候我們應當先去載入圖片但並不渲染動圖,動圖播放和停止唯一的判斷標準是滑入滑出螢幕的長度,如果是快速滑動則無視第二個規則直接停止所有的動圖。
上面的第二、第三個處理會有些許的程式碼量,而且重點是時機的判斷不是動圖的處理,這裡著重講策略,程式碼就略過了。對於第一個處理,Fresco本身是支援的:
DraweeController controller = Fresco.newDraweeControllerBuilder() .setUri(uri) .setAutoPlayAnimations(false) . // 其他設定(如果有的話) .build();
setAutoPlayAnimations即表示是否在載入完成之後立即播放動圖,這裡設定為false即可,滑入播放呼叫上一張圖的方法就行了。可是還有一種情況,動圖在我們滑入的時候還沒有載入完成,那麼我們就可以設定一個標示來表示是否播放,因為SimpleDrwaView是可以拿到動圖載入的回撥的:
ControllerListener controllerListener = new BaseControllerListener<ImageInfo>() { @Override public void onFinalImageSet( String id, @Nullable ImageInfo imageInfo, @Nullable Animatable anim) { if (anim != null && tag == BEGAIN) { // 其他控制邏輯 anim.start(); } } };
滑入螢幕時,就把tag 置為BEGAIN,滑出再置空就行了,並且這裡我們不用擔心重複播放和停止的問題,這裡的anim物件其實是AnimatedDrawble2物件,而該物件在start和stop的時候都對狀態進行了判斷。
圖片的規格尺寸
-
規格
相較於傳統的gif,同質量的webp體積更小,更能節省儲存空間,但是在解碼上webp更為耗時,所以能用webp儘量用webp,實在還是卡再考慮用gif。
-
幀率
目前調研發現的動圖幀率一般是10幀或者20幀,幀率不要太高了,不然會加大cpu的佔用率,其實如果Fresco的使用方式沒出問題,記憶體的問題Fresco已經幫你搞定了,其他的優化主要是針對cpu佔用率優化的。在專案中我們載入的動圖最後採用的是20幀(模仿騰訊謀產品的策略,最好控制在10幀其實,這款騰訊的產品在一頁上展示的動圖明顯比其他同類型產品展示的數量少)。
-
大小
動圖的大小也會影響解碼耗時,在手機端可以使用小圖,在專案中,我們手機端的動圖最多在200kb左右。
在實際的開發中,可能因為業務的關係,上述的策略不能保證全部都做到,這裡時候就得根據業務形態做對應的取捨,這裡可能是一個長久優化的過程,畢竟這種新的動圖封面設計以前都沒有遇到過。