ListView緩存機制

ListView在RecyclerView出現之前是列表使用最多的控件,它自然是有它的優勢的,而ListView的緩存機制也是面試常考的問題之一。下面就簡單說一說ListView的緩存機制。

一、RecycleBin緩存機制

RecycleBin是寫在AbsListView中的,而ListView繼承於AbsListView,也自然繼承了這個機制。

變量

1、private View[] mActiveViews : 緩存屏幕上可見的view

2、private int mViewTypeCount : ListView中子佈局不同類型的類型總數

3、ArrayList<View>[] mScrapViews : ListView中所有的廢棄緩存。這是一個數組,每一種佈局類型的view都有一個自己的arraylist緩存。

4、ArrayList<View> mCurrentScrap : 當前childView佈局類型下的緩存

方法

1、 void fillActiveViews() : 此方法將listview中指定元素存放到mActiveViews中

2、View getActiveView() : 從mActiveViews中取出指定元素,取出view後,該位置元素將被置空。

3、addScrapView() : 將一個廢棄view置入緩存。如果佈局類型只有一項,則直接存入mCurrentScrap中,如果有多項,從mScrapViews中找到對應廢棄緩存並存儲。

4、View getScrapView() : 與addScrapView對應,從相應類型的緩存中,取出view。

5、setViewTypeCount() : 爲mViewTypeCount設置佈局類型總數,同時爲每一種佈局類型啓動一個RecycleBin機制。

RecycleBin緩存機制原理,當一個view滑出界面時,會調用addScrapView方法,將view緩存,當一個view進入頁面時,會調用getScrapView方法獲取一個view。adpater中的getView方法裏的convertView正是取出來的view,如果爲空就說明緩存中已經沒有view了,需要我們inflate一個。之後就是對holder的操作。

二、如何區分佈局類型

那麼listview是如何區分緩存的view是哪一種類型呢。看下面兩張圖。



第一張是設置佈局類型數量的方法,可以看到設置完佈局類型數量後,爲每一種佈局類型都創建了一個arrayList存放view。而圖二中,mAdapter的getItemViewType方法,便獲取到了這個view的類型。看到這裏也明白了,爲什麼getItemViewType的返回值一定要小於getItemTypeCount,因爲是以這個值爲腳標,從arraylist數組中取值。至於這個LayoutParams中爲什麼會有viewType,那是因爲absListView自己重寫了LayoutParams,增加了這個變量,用於區分佈局類型。


好了,到這裏大多數的疑問就都解決了吧。唯一不太清楚的可能就是滑動時候的觸發事件了,在那些事件裏,調用了listview的這一套recycleBin緩存機制。有興趣的讀者,自行去讀源碼吧。