一、問題描述
ListView顯示資料時,自定義了一個擴充卡(extends BaseAdapter),然後重寫了getView方法,現在出現一個問題,就是這個getView()方法被重複調用了,比如我的_data中有兩條資料,但是log.i("show",house.toString());這句卻被執行了4次甚至更多。
二、原因分析
getView()被調用的次數取決于目前螢幕能顯示的item的數量,顯示一個item就調用一次。當listview的layout_height屬性是wrap_content時,有可能造成listview無法計算高度,相應的需要顯示的item數量就無法計算,造成getView多次被調用。
三、解決辦法
1、ListView重複調用getView解決辦法:
ListView布局時height和width都不是match_parent,導緻不斷計算高度,不斷重新整理。或者說它的父容器沒有設定成match_parent. 我們隻需要設定ListView為固定寬高即可。注意:如果還是不行,記得檢視是否是父容器沒有設定為match_parent
listView布局xml檔案修改前:
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
修改前getView()代碼
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.d(TAG, "getView: position = " + position);
return convertView;
}
修改前列印log:
修改後:
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
修改後列印log:
二、GridView重複調用getView解決辦法:
1、首先在getView方法中加上列印日志,代碼如下:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int childCount = parent.getChildCount();
Log.d(TAG, "getView: position = " + position + ", childCount = " + childCount);
return convertView;
}
2、列印日志如下,标記為紅框的地方為getView重複調用:
3、原因分析及解決方法:GridView寬高設定為match_parent, 仍會出現多次調用getView的問題。由上面日志可以看到,當position != childCount 且position = 0且時,此時為getView重複調用。雖然暫無好的方法禁止GridView重複調用getView, 但我們可以判斷重複調用getView時,直接傳回convertView即可。
代碼修改前:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int childCount = parent.getChildCount();
Log.d(TAG, "getView: position = " + position + ", childCount = " + childCount);
ViewHolder vh;
if (convertView == null) {
vh = new ViewHolder();
return convertView
}
代碼修改後:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int childCount = parent.getChildCount();
Log.d(TAG, "getView: position = " + position + ", childCount = " + childCount);
ViewHolder vh;
// 按方向鍵或者ImageLoader加載縮略圖都會重複調用兩次getView,導緻卡頓。當判斷為重複調用時
直接傳回convertView
if (position != childCount && position == 0 && convertView != null) {
Log.d(TAG, "getView duplicate, return");
return convertView;
}
if (convertView == null) {
vh = new ViewHolder();
return convertView
}