相信很多人在使用ListView的時候都要進行ListView優化,所採用的方法便是Holder,代碼如下
ViewHolder holder = null;
if(convertView == null){
convertView = mInflater.inflate(R.layout.xxx null);
holder = new ViewHolder();
holder.tvXXX= (TextView)findViewById(R.id.xxx);
//...一連串的findViewById
}else{
holder = (ViewHolder) convertView.getTag();
}
private static class ViewHolder{
TextView tvXXX;
//很多view的定義
}
在少量使用ViewAdapter的時候使用這種寫法還是可以的,但當我們大量使用的時候就顯得有些麻煩了。外網站上看的,一個比較簡潔的設計。
ViewHolder這麼寫(只提供一個靜態方法,其實可以加一個私有構造函數防止外部實例化),代碼很簡單,看過就明白了
public class ViewHolder {
client code
@SuppressWarnings("unchecked")
//靜態方法,返回類型爲一個泛型
public static T get(View view, int id) {
//關於SpareArray的使用說明詳細見[這裏寫鏈接內容] (http://blog.csdn.net/easyer2012/article/details/37871031)
SparseArray viewHolder =(SparseArray) view.getTag();
if (viewHolder == null) {
//如果爲空則創建viewHolder
viewHolder = new SparseArray();
view.setTag(viewHolder);
}
//更具key拿到value
View childView = viewHolder.get(id);
if (childView == null) {
childView = view.findViewById(id);
viewHolder.put(id, childView);
}
return (T) childView;
}
}
在getView裏這樣
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.banana_phone, parent,false);
ImageView bananaView = ViewHolder.get(convertView, R.id.banana);
TextView phoneView = ViewHolder.get(convertView, R.id.phone);
//這是一個數據list
BananaPhone bananaPhone = getItem(position);
phoneView.setText(bananaPhone.getPhone());
bananaView.setImageResource(bananaPhone.getBanana());
return convertView;
}
說明:這種Holder的核心在於封裝一個SparseArray用來存放Item中的View的id和View本身,在第一次創建Holder的時候SparseArray爲空
便通過如下代碼來填充SparseArray
childView = view.findViewById(id);
viewHolder.put(id, childView);