对ListView数据错乱的一些情况进行记录:
- ViewHolder内部的控件没有写好
- List数据的处理
- 适配器的getView方法,view.getTag()方法重用问题导致的数据为null时仍有数据的问题
这里主要注意的是第三条,if (view != null) 时,理所当然的应该使用
vh = (MyViewHolder) view.getTag();
来获取对应的控件对象,达到重用ListViewItem资源的一个目的,但是当其中有些内容为Null时,我们对List进行了判断,为Null时不会对相应控件进行设值
@Override
public View getView(int i, View view, ViewGroup group) {
MyViewHolder vh = null;
if (view == null) {
vh = new MyViewHolder();
view = LayoutInflater.from(mContext).inflate(R.layout.item_nullview, group, false);
vh.itemNullView_ImageView = (ImageView) view.findViewById(R.id.itemNullView_ImageView);
vh.itemNullView_TextView = (TextView) view.findViewById(R.id.itemNullView_TextView);
view.setTag(vh);
} else {
vh = (MyViewHolder) view.getTag();
}
//position为5时什么都不做
if (i == 5) {
} else {
vh.itemNullView_TextView.setText(mList.get(i));
}
return view;
}
Item XML对应的TextView控件高度设置为了200dp方便观察
List.size()长度也填充为20
<TextView
android:id="@+id/itemNullView_TextView"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:gravity="center"/>
最终会看到:当listview的position滑动到5时,这时第五个item应该是一个空白区域。但最终会看到它是有值的,这个值为listview由于上滑而被隐藏(“隐藏”这个词不是很恰当,不过就那意思)的item的值,出现这个现象的原因是由于我们view.getTag()方法,当View非空时会使用这个方法进行资源重用,但因某些原因我们没有给他设置相应的值,从而导致了view.getTag()拿到的这个资源为被隐藏的缓存资源,之后的view对应的子对象没有发生任何改变,显然,在getView的返回对象 return view; 返回的是之前拿到的缓存资源数据。
解决这个问题的方法有很多,可以让当数据位null时给对应的控件一个”“空字符串。这个没啥好说的。。PS:RecycleView.Adapter无此问题~~~具体的可自行查看源码