listView中多個listItem佈局時,convertView快取及使用
原創教程,轉載請保留出處:http://www.eoeandroid.com/thread-72369-1-1.html
最近有需求需要在listView中載入不同的listItem佈局,開始沒有使用convertView,載入了多個item後導致了記憶體洩露,所以回來研究convertView在多個listItem佈局時的快取及應用,並且和大家分享
構造Adapter時,沒有使用快取的 convertView,導致記憶體洩露
示例程式碼:
public View getView(int position, View convertView, ViewGroup parent) {
View view = new Xxx(...);
... ...
return view;
}
public View getView(int position, View convertView, ViewGroup parent) {
View view = new Xxx(...);
... ...
return view;
}
描述:
以構造ListView的BaseAdapter為例,在BaseAdapter中提供了方法:
public View getView(int position, View convertView, ViewGroup parent){ }
來向ListView提供每一個item所需要的view物件。初始時ListView會從BaseAdapter中根據當前的螢幕佈局例項化一定數量的view物件,同時ListView會將這些view物件快取起來。當向上滾動ListView時,原先位於最上面的list item的view物件會被回收,然後被用來構造新出現的最下面的list item。這個構造過程就是由getView()方法完成的,getView()的第二個形參 View convertView就是被快取起來的list item的view物件(初始化時快取中沒有view物件則convertView是null)。
由此可以看出,如果我們不去使用convertView,而是每次都在getView()中重新例項化一個View物件的話,即浪費資源也浪費時間,也會使得記憶體佔用越來越大。
修正示例程式碼:
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView != null) {
view = convertView;
...
} else {
view = new Xxx(...);
...
}
return view;
}
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView != null) {
view = convertView;
...
} else {
view = new Xxx(...);
...
}
return view;
}
上述程式碼很好的解決了記憶體洩露的問題,使用convertView回收一些佈局供下面重構是使用。
但是如果出現如下圖的需求,convertView就不太好用了,convertView在Item為單一的佈局時,能夠回收並重用,但是多個Item佈局時,convertView的回收和重用會出現問題。Listview中有3種Item佈局,即使convertView快取了一些佈局,但是在重構時,根本不知道怎麼樣去讓convertView返回你所需要的佈局,這時你需要讓adapter知道我當前有哪些佈局,我重構Item時的佈局選取規則,好讓convertView能返回你需要的佈局
需要重寫一下兩個函式
@Override
public int getItemViewType(int position) {}
官網解釋如下,不解釋了Get the type of View that will be created by getView(int, android.view.View, android.view.ViewGroup)]getView(int, View, ViewGroup) for the specified item.
Parameters
Returns
-
An integer representing the type of View. Two views should share the same type if one can be converted to the other in getView(int, android.view.View, android.view.ViewGroup)getView(int, View, ViewGroup).
Note: Integers must be in the range 0 to getViewTypeCount() -
1. IGNORE_ITEM_VIEW_TYPE can
also be returned.
@Override
public int getViewTypeCount() {}
Get the type of View that will be created by getView(int, android.view.View, android.view.ViewGroup)getView(int, View, ViewGroup) for the specified item.
Parameters
Returns
-
An integer representing the type of View. Two views should share the same type if one can be converted to the other in getView(int, android.view.View, android.view.ViewGroup)getView(int, View, ViewGroup).
Note: Integers must be in the range 0 to getViewTypeCount() -
1. IGNORE_ITEM_VIEW_TYPE can
also be returned.
上述兩個函式的作用這如它的名字,得到Item的樣式,得到所有的樣式數量
下面直接上程式碼,就是上圖的實現程式碼:
在getView()中需要將不同佈局進行快取和適配,系統在判斷是否有convertView時,會自動去呼叫getItemViewType (int position) ,檢視是否已經有快取的該型別的佈局,從而進入if(convertView == null)和else{}的判斷。期間需要做的是convertView.setTag(holder3),以便在convertView重用時可以直接拿到該佈局的控制元件,holder3 = (viewHolder3) convertView.getTag()。到這一步,convertView的回收和重用就已經寫好了,接下來只需要對你的不同的控制元件進行設定就行了。
如有不正確或者我理解錯誤的地方,大家輕拍!
相關文章
- 利用convertView優化ListView效能View優化
- 多個快取盒子疊加使用快取
- QGIS列印佈局中繪製多個子圖
- ListView項(Item)的三種佈局View
- Android回顧--(十) ListView的優化和多佈局複用AndroidView優化
- getView()不復用convertView,ListView即毫無複用!(ListView回收機制)View
- Flutter 佈局(十)- ListBody、ListView、CustomMultiChildLayout詳解FlutterView
- CSS及佈局CSS
- nginx快取使用詳解,nginx快取使用及配置步驟Nginx快取
- 使用 Infinispan 快取功能支援多個 Redis 資料庫快取Redis資料庫
- Android listView奇偶項採用不同的佈局AndroidView
- ListView的複用和快取機制View快取
- 再次探究Android ListView快取機制AndroidView快取
- 深入理解Android中的快取機制(二)RecyclerView跟ListView快取機制對比Android快取View
- 淺談Flex佈局的屬性及使用Flex
- Flutter 開發從 0 到 1(三)佈局與 ListViewFlutterView
- 十個常見的快取使用誤區及建議快取
- Grid 佈局-子項補充及常用佈局
- Android一個小知識點: 多個介面同時使用一個資源佈局的時候,修改背景需要注意的坑Android
- unbound中快取時間邏輯快取
- CSS多種佈局方式自我實現-水平佈局(二)CSS
- ListView中使用自定義Adapter及時更新資料ViewAPT
- Web 開發者如何理解 Flutter 佈局之 —— 5. ListView 和 ScrollBarWebFlutterView
- CSS-佈局7-多列自動劇中CSS
- AngularJS中的$http快取以及處理多個$http請求AngularJSHTTP快取
- 赫斯特中國佈局元宇宙,多個IP公佈,陣容豪華!元宇宙
- CSS佈局–聖盃佈局和雙飛翼佈局以及使用Flex實現聖盃佈局CSSFlex
- 使用 yogaKit 實現一個資訊流佈局
- Avalonia中的佈局
- 快取及使用 Circuit Breaker 限制記憶體使用快取UI記憶體
- iOS中AutoLayer自動佈局流程及相關方法iOS
- Android中View的量算、佈局及繪圖機制AndroidView繪圖
- Flutter 中 ListView 的使用FlutterView
- 開源專案MergeAdapter,實現ListView複雜佈局APTView
- 程式設計中快取的使用程式設計快取
- C#中普通快取的使用C#快取
- 快取使用中的注意事項快取
- 【Redis】快取穿透,快取擊穿,快取雪崩及解決方案Redis快取穿透