ViewHolder

其实还是用convertView/ViewHolder 这种缓存技术比较好,这样子你浏览ListView的时候速度很快。而不采用convertView/ViewHolder 这种缓存技术的时候,你会明显感觉ListView很卡。convertView/ViewHolder 缓存技术的实质,其实就是convertView的复用,因为我在查看convertView是否为null的时候,只有7次它输出null,其余都是convertView不为null。也就是说convertView这个对象引用只有7个(每个手机不同,就是一个屏幕最多容纳的条目数)。convertView/ViewHolder 其实是在复用每一个条目的View。只让这7个引用对应7个View的实例,而不是我们每次都给一个引用建立一个新的View实例。这样子,在ListView绘制调用getView的时候,我们只建立了7个View实例,只是每次把View中的内容改变了一下,比如TextView.setText(str)。这样子程序就很快。


我的adapter编写如下:

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
      
      
public class VouchersAdapter extends BaseAdapter implements OnClickListener {
private Context mContext;
private List<VouchersModel> mList;
private ImageLoader imageLoader;
public VouchersAdapter(Context context, List<VouchersModel> list) {
this.mContext = context;
this.mList = list;
this.imageLoader = ImageLoader.getInstance();
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(
R.layout.adapter_vouchers, null);
holder.iv = (ImageView) convertView
.findViewById(R.id.iv_vouchers_image);
holder.tvName = (TextView) convertView
.findViewById(R.id.tv_vouchers_desp);
holder.tvIntegral = (TextView) convertView
.findViewById(R.id.tv_vouchers_needintegral);
holder.tvResidue = (TextView) convertView
.findViewById(R.id.tv_vouchers_residue);
holder.tvExchange = (TextView) convertView
.findViewById(R.id.tv_vouchers_exchange);
holder.rlVouchers = (RelativeLayout) convertView
.findViewById(R.id.rl_vouchers);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
VouchersModel model = mList.get(position);
imageLoader.displayImage(
ConnectNetworkConstant.HOST_URL + model.getPicUrl(), holder.iv);
holder.iv.setTag(ConnectNetworkConstant.HOST_URL + model.getPicUrl());
holder.tvName.setText(model.getCouponNm());
holder.tvIntegral.setText(String.valueOf(model.getNeedIntegral())
+ "积分");
holder.tvResidue.setText("剩余:"
+ String.valueOf(model.getRemainQuantity()) + "件");
holder.tvExchange.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
}
});
holder.rlVouchers.setTag(model);
holder.rlVouchers.setOnClickListener(this);
return convertView;
}
private final class ViewHolder {
private ImageView iv;
private TextView tvName;
private TextView tvIntegral;
private TextView tvResidue;
private TextView tvExchange;
private RelativeLayout rlVouchers;
}
@Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.rl_vouchers:
VouchersModel model = (VouchersModel) arg0.getTag();
Intent intent = new Intent(mContext, VouchersDetailActivity.class);
intent.putExtra("model", model);
mContext.startActivity(intent);
break;
default:
break;
}
}
}

         涉及到加载图片,经常会出现重复。出现重复内容,基本上都是使用了ViewHolder这种方法的。

       当我们判断 convertView == null  的时候,如果为空,就会根据设计好的ListItem布局(XML),来为convertView赋值,并生成一个viewHolder来绑定converView里面的各个View控件(XML布局里面的那些控件)。再用convertViewsetTagviewHolder设置进去。

如果convertView不为空的时候,就会直接用convertViewgetTag(),来获得一个ViewHolder


      ListView只会缓存第一屏里面的List Item的视图布局,之后滚动ListView后面的Item的布局就都是用前面所缓存的视图布局(也就是convertView不为null)。这样如果当后面的某一条记录里面的某些控件因上面的原因没有赋值,就会直接使用前面所缓存的视图里面的值了(里面有值的话)。

  这样的最终效果就是,滚动的时候,会出现前面已经出现过的内容。

      解决办法:

如果子控件为ImageView,当赋值内容为空时,直接设定默认的图像资源。如果使用setBackgroundResource可能出现默认的图像资源没有真正的设定到ImageView,必须使用setImageResource。setBackgroundResource是View类中的方法,而setImageResource是ImageView自己的方法。使用前者可能导致图像没有真正的设定到ImageView,此时ImageView显示上一次赋值的图像。

if (holder.iv.getTag() != null
&& !holder.iv.getTag().toString().equals(ConnectNetworkConstant.HOST_URL+model.getPicUrl().toString())) { // 解决图片显示错位
holder.iv.setImageResource(R.drawable.default_image_185_140);
}




  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值