相信很多人在使用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);