今天在做项目的时候,发现ListView的显示出问题了,具体情况是这样的:ListView上的每个item显示的是每个用户的信息,当在滑动ListView后,出现了其他的用户信息显示在不是属于他的item上的BUG,经过网上查找相关信息后,原因是出在getView这个方法里,因为重复利用convertView导致的结果,下面是代码:
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { View v = LayoutInflater.from(context).inflate( R.layout.listview_item, null); viewHolder = new ViewHolder(); viewHolder.txtname = (TextView) v.findViewById(R.id.txtname); viewHolder.imgremoteicon = (ImageView) v.findViewById(R.id.imgremoteicon); viewHolder.txtsignature = (TextView) v.findViewById(R.id.txtsignature); viewHolder.txtlatesttime = (TextView) v.findViewById(R.id.txtlatesttime); v.setTag(viewHolder); convertView = v; } else { viewHolder = (ViewHolder) convertView.getTag(); } if (list != null) { final PeopleModel mPeopleModel = list.get(position); if (mPeopleModel != null) { Log.e(TAG, "icons=" + mPeopleModel.icon); if (!TextUtils.isEmpty(mPeopleModel.icon)) { ImageLoader.getInstance().displayImage(mPeopleModel.icon, viewHolder.imgremoteicon, options,animateFirstListener); }
if (!TextUtils.isEmpty(mPeopleModel.username)) { viewHolder.txtname.setText(mPeopleModel.username); } if (!TextUtils.isEmpty(mPeopleModel.sign)) { viewHolder.txtsignature.setText(mPeopleModel.sign); }
viewHolder.txtlatesttime.setText(DateUtil.getLatestLoginTime( (long) mPeopleModel.last_update, context)); } return convertView; }
那么问题来了,当不滑动ListView是没有问题的,因为一开始convertView是为空,在构建convertView的时候就会创建一个ViewHoler对象且这个对象里面没有任何数据,并将这个对象通过setTag设置进去,通过这个对象为convertView的各个控件赋值,当ListView向下滑动时,最上面的item不可见,最下面出现了一个新的item,这个时候并不会再构建一个convertView,而是用了之前构建好的convertView,并通过getTag得到ViewHolder对象,这个时候ViewHolder对象里面是有数据的,当程序执行到新的item出现,adapter要为convertView各个控件赋值,但当有的控件需要对数据加以判断后才能赋值,例如上面的代码,当条件不满足时就会跳过对这个控件的赋值,但是前面的某一个item上的这个控件是有赋值的,所以这个新的item就会使用原来缓存的convertView中的值,这就造成了在新的item出现后,会出现视图重复的问题.
所以解决的办法就是,对于不满足条件就不能赋值的控件加上一个else语句,给定一个默认值,所以在上面的代码中在if判断完后加个else对控件赋值,就解决了我目前的BUG.
这是我的第一篇博客,希望能在这里记录自己学习上的点点滴滴,也希望能在这里有所收获,有所成长.