ListView優化:通過convertView+ViewHolder來實作,ViewHolder就是一個靜态類,使用 ViewHolder 的關鍵好處是緩存了顯示資料的視圖(View),加快了 UI 的響應速度。
當我們判斷 convertView == null 的時候,如果為空,就會根據設計好的List的Item布局(XML),來為convertView指派,并生成一個viewHolder來綁定converView裡面的各個View控件(XML布局裡面的那些控件)。再用convertView的setTag将viewHolder設定到Tag中,以便系統第二次繪制ListView時從Tag中取出。(看下面代碼中)
如果convertView不為空的時候,就會直接用convertView的getTag(),來獲得一個ViewHolder。
//在外面先定義,ViewHolder靜态類
static class ViewHolder
{
public ImageView img;
public TextView title;
public TextView info;
}
//然後重寫getView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if
(convertView ==
null
)
{
holder =
new
ViewHolder();
convertView = mInflater.inflate(R.layout.list_item,
null
);
holder.img = (ImageView)item.findViewById(R.id.img)
holder.title = (TextView)item.findViewById(R.id.title);
holder.info = (TextView)item.findViewById(R.id.info);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
holder.img.setImageResource(R.drawable.ic_launcher);
holder.title.setText(
"Hello"
);
holder.info.setText(
"World"
);
}
return
convertView;
}
到這裡,可能會有人問ViewHolder靜态類結合緩存convertView與直接使用convertView有什麼差別嗎,是否重複了
在這裡,官方給出了解釋
緩存convertView傳遞給getView()方法來避免填充不必要的視圖
使用ViewHolder模式來避免沒有必要的調用findViewById():因為太多的findViewById也會影響性能
ViewHolder模式通過getView()方法傳回的視圖的标簽(Tag)中存儲一個資料結構,這個資料結構包含了指向我們
要綁定資料的視圖的引用,進而避免每次調用getView()的時候調用findViewById()