Android列表動圖展示的實現(xiàn)策略
前言
在最近的時間里,短視頻流行了起來,隨著這股潮流,一種動圖封面的設(shè)計也被很多短視頻app采用:

某音
而在app中,動圖的展示是比較消耗性能的操作,對于這種一頁非常多的動圖在展示時需要做對應(yīng)的處理,今天我結(jié)合自己在項目中處理的經(jīng)驗分享一下多動圖的處理策略。
圖片加載框架選擇
對于動圖的加載,尤其是webp格式的動圖,F(xiàn)resco真是不二的選擇,而且fresco本身對內(nèi)存的處理也很棒,本文是基于Fresco 1.0.10版本,如果使用低版本Fresco出現(xiàn)無解的問題時,不妨可以試著升級Fresco版本。
圖片展示的策略
只在當(dāng)前頁展示
我們知道,動圖是由一幀一幀的靜圖組成的,通常來說我們需要這個動圖一直播放,也就是說動圖從加載完成之后會不停的渲染每一幀,拿某音舉例:

首頁
假設(shè)下面的“首頁”“、”關(guān)注”、“消息”、“我”4個tab都有動圖,當(dāng)我們點擊其他頁面時,當(dāng)前頁被隱藏,而根據(jù)Fresco的官方文檔Fresco中文官方文檔通常只有當(dāng)SimpleDrawView被移出屏幕才會停止播放動畫(我在測試中發(fā)現(xiàn)通常Activity生命周期級別的也會觸發(fā)),所以當(dāng)tab頁隱藏時動圖依舊在被渲染,所以我們需要控制動圖的停止和播放,只有當(dāng)前頁展示時,才播放動圖:
Animatable animatable = mSimpleDraweeView.getController().getAnimatable();
if (animatable != null) {
animatable.start();
// later
animatable.stop();
}
只在可見區(qū)域展示
當(dāng)我們做列表動圖的時候,無論控件是listview還是recyclerview,數(shù)據(jù)和item的綁定都會在屏幕外綁定,而此時站在性能優(yōu)化的角度上,是不需要渲染動圖的;當(dāng)動圖滑動在列表邊界的時候,是不是說明用戶的焦點已經(jīng)不在這張圖上了,所以此時可以提前在動圖滑出屏幕外之前停止動圖播放(在項目中我與產(chǎn)品商定動圖播放和停止的邊界值定為圖片的1/2,也就是說圖片滑入屏幕自身長度1/2的時候播放動圖,滑出屏幕自身長度1/2的時候停止播放);當(dāng)快速滑動的時候也應(yīng)當(dāng)停止動圖渲染(平時加載靜圖可能不需要在意,但是在android老手機上加載很多動圖會使得cpu和內(nèi)存大幅度浮動)。
也就是說當(dāng)列表在做數(shù)據(jù)綁定的時候我們應(yīng)當(dāng)先去加載圖片但并不渲染動圖,動圖播放和停止唯一的判斷標(biāo)準(zhǔn)是滑入滑出屏幕的長度,如果是快速滑動則無視第二個規(guī)則直接停止所有的動圖。
上面的第二、第三個處理會有些許的代碼量,而且重點是時機的判斷不是動圖的處理,這里著重講策略,代碼就略過了。對于第一個處理,F(xiàn)resco本身是支持的:
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(uri)
.setAutoPlayAnimations(false)
. // 其他設(shè)置(如果有的話)
.build();
setAutoPlayAnimations即表示是否在加載完成之后立即播放動圖,這里設(shè)置為false即可,滑入播放調(diào)用上一張圖的方法就行了??墒沁€有一種情況,動圖在我們滑入的時候還沒有加載完成,那么我們就可以設(shè)置一個標(biāo)示來表示是否播放,因為SimpleDrwaView是可以拿到動圖加載的回調(diào)的:
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,滑出再置空就行了,并且這里我們不用擔(dān)心重復(fù)播放和停止的問題,這里的anim對象其實是AnimatedDrawble2對象,而該對象在start和stop的時候都對狀態(tài)進行了判斷。
圖片的規(guī)格尺寸
規(guī)格
相較于傳統(tǒng)的gif,同質(zhì)量的webp體積更小,更能節(jié)省存儲空間,但是在解碼上webp更為耗時,所以能用webp盡量用webp,實在還是卡再考慮用gif。
幀率
目前調(diào)研發(fā)現(xiàn)的動圖幀率一般是10幀或者20幀,幀率不要太高了,不然會加大cpu的占用率,其實如果Fresco的使用方式?jīng)]出問題,內(nèi)存的問題Fresco已經(jīng)幫你搞定了,其他的優(yōu)化主要是針對cpu占用率優(yōu)化的。在項目中我們加載的動圖最后采用的是20幀(模仿騰訊謀產(chǎn)品的策略,最好控制在10幀其實,這款騰訊的產(chǎn)品在一頁上展示的動圖明顯比其他同類型產(chǎn)品展示的數(shù)量少)。
大小
動圖的大小也會影響解碼耗時,在手機端可以使用小圖,在項目中,我們手機端的動圖最多在200kb左右。
在實際的開發(fā)中,可能因為業(yè)務(wù)的關(guān)系,上述的策略不能保證全部都做到,這里時候就得根據(jù)業(yè)務(wù)形態(tài)做對應(yīng)的取舍,這里可能是一個長久優(yōu)化的過程,畢竟這種新的動圖封面設(shè)計以前都沒有遇到過。
總結(jié):
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
非常實用的小功能 Android應(yīng)用版本的更新實例
這篇文章主要為大家詳細(xì)介紹了一個非常實用的小功能,Android應(yīng)用版本的更新實例,感興趣的小伙伴們可以參考一下2016-08-08
java,Android:在eclipse中的快捷鍵(經(jīng)典收藏)
下面的快捷鍵是常用的,本人就本身喜好且常用的收拾一下,現(xiàn)在曬出來與大家分享,感興趣的朋友可以了解小哦2013-01-01
Kotlin利用Regex如何構(gòu)建正則表達(dá)式詳解
正則表達(dá)式,又稱規(guī)則表達(dá)式。下面這篇文章主要給大家介紹了關(guān)于Kotlin利用Regex構(gòu)建正則表達(dá)式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。2017-12-12
Android開發(fā)之Button事件實現(xiàn)與監(jiān)聽方法總結(jié)
這篇文章主要介紹了Android開發(fā)之Button事件實現(xiàn)與監(jiān)聽方法,結(jié)合實例形式總結(jié)分析了Android開發(fā)中Button事件的兩種實現(xiàn)方法以及針對Button控件的幾種常用監(jiān)聽方法,需要的朋友可以參考下2016-01-01
設(shè)置Android設(shè)備WIFI在休眠時永不斷開的代碼實現(xiàn)
這篇文章主要介紹了設(shè)置Android設(shè)備WIFI在休眠時永不斷開的代碼實現(xiàn),需要的朋友可以參考下2014-07-07
Android 自定義Button控件實現(xiàn)按鈕點擊變色
這篇文章給大家介紹了android 自定義Button控件實現(xiàn)按鈕點擊變色的代碼,本文給大家附有注釋,非常不錯,代碼簡單易懂,對android按鈕點擊變色的實現(xiàn)感興趣的朋友參考下吧2016-11-11
Android編程視頻播放API之MediaPlayer用法示例
這篇文章主要介紹了Android編程視頻播放API之MediaPlayer用法,結(jié)合實例形式分析了基于Android API實現(xiàn)視頻播放功能的多媒體文件讀取、判斷、事件響應(yīng)及流媒體播放等相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2017-08-08

