Android ListView中複雜數據流的高效渲染(一)

更新:目前已經寫了demo,歡迎討論:Android複雜數據流的「高效」渲染javascript

咱們知道Android中的ListView之因此能夠實現item的無限加載,是由於對每一個item的View 進行了緩存複用。ListView的高效性能使得其在App開發中使用很是頻繁,本文主要分析在複雜數據展現時如何更加高效的使用ListView,如微博、facebook、twitter等的feed流須要展現很是多的數據類型:新聞、圖片、網頁連接、視頻,這種狀況下ListView進行須要緩存各類類型的View,App的內存佔用急劇升高……java

ListView複用原理

1. 簡單列表複用

首先簡單介紹一下ListView的複用原理,咱們知道使用ListView時通常須要結合Adapter使用,繼承BaseAdapter時,通常須要實現四個方法:緩存

@Override
    public int getCount() {
        return 0;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return null;
    }複製代碼

其中getView是渲染每一個Item時進行回調生成View的,方法參數convertView就是ListView傳回能夠複用的View,當其不爲null時,無需從新建立View,能夠直接使用convertView,進行數據渲染便可。其原理是當第一次調用時ListView直接將生成的View緩存到一個ArrayList 中,當須要時直接從ArrayList中取出便可: ide

Paste_Image.png

2. 複雜列表複用

當列表中有多種類型的view時,咱們須要實現BaseAdapter中的:性能

@Override
    //返回view類型數量
    public int getViewTypeCount() {
        return super.getViewTypeCount();
    }

    @Override
    //返回每一個Item的類型
    public int getItemViewType(int position) {
        return super.getItemViewType(position);
    }複製代碼

這種狀況下ListView實際爲每種類型的Item設置了一個ArrayList進行緩存:優化

Paste_Image.png

複雜信息流

此處以微博爲例:ui

  • 轉發帶視頻類型
    Paste_Image.png
  • 普通文字+卡片類型

  • 轉發圖文類型


此外還有原創圖文類型,原創視頻,原創卡片,系統通知,轉發視頻,轉發圖文,……,微博有多達二十種左右的item類型,每種類型中的View可能包括頭部圖片、文字描述、正文內容、正文圖片、正文視頻、分享操做欄等內容,這些都緩存到內存中,再加上二十多種類型,想一想內存的感覺……

優化

咱們能夠看到不少類型中都有相同能夠複用的部分,如頭部、分享操做欄等不少item中都是同樣,是否可單獨拿出來呢,咱們進行簡單的拆分:spa

Paste_Image.png

一個Item咱們把它拆爲來五個部分, 首先頭部、評論操做欄等能夠在不少不一樣類型的數據Item中進行復用,文字、圖片等的View也能夠單獨進行復用,並且最重要的是:緩存ArrayList中保存的View數量將會減小,內存消耗減了很多

具體實現中的坑

看到這裏,是否是不少同窗以爲打開了新世界的大門,急着進行代碼的優化?具體的代碼不方便貼出來,這裏說一下具體實現過程當中碰到的坑:3d

  • item click事件
    因爲優化的需求,把邏輯上的一個Item拆分爲了多個item,所以每一個item上都要設置ItemClick事件。具體實現時能夠寫一個基類,在基類中對item click進行處理。
  • cover 按壓效果
    在item 點擊時,通常須要有按壓效果,此時邏輯上的item已經進行了拆分,須要策略實現邏輯上item的總體按壓,而不是隻有某個拆分後的item被按壓。
  • divider
    咱們知道listview的item之間是有divider的,此時須要設置divider爲null,咱們經過添加item的方式來實現divider效果。

效果

等填完拆分後的坑,運行程序,觀察先後的效果,內存佔用能夠減小10~20m,滑動流暢度也提升很多,在低端手機上的效果尤爲明顯,掉幀明顯減小。很是建議有須要的同窗嘗試。code

Other

歡迎關注公衆號wutongke,天天推送移動開發前沿技術文章:

wutongke
相關文章
相關標籤/搜索