避免 ListView 的 控件重用机制 导致视图/数据混乱

控件视图重用,就是当convertView不为空的时候直接重新使用convertView从而减少了很多不必要的View的创建,然后加载数据当列表往上下拖时,那些被拖出屏幕外的控件会重用。当触发器被触发时,触发该控件的OnCheckedChanged处理程序,而这个处理程序指向的数据项是前一次绑定的btnListbutton的数据,这样就可能导致视图混乱

【错误案例】

(这里使用ExpandableListView expandableListView;Button在Group中,checkBox在child中,点击child的checkBox 会触发checkedChanged 操作,改变Group 的Button 的内容。

 

BaseExpandableListAdapter中的getGroupView如下:

ChildViewcheckBox OnCheckedChangedListener onChenckedChanged() 如下:


【错误案例演示】

一开始生产所有Group时,btnList 中的0123....分别与 group Item 0123...对应;

这时对btnList0元素Button的操作,是没问题的:

但是,当第一个item的控件视图被移出当前界面时,后面新的item会将其利用起来,导致新的item莫名其妙地被改变了:


随着不断的上下翻动,item的控件视图将愈发混乱。

【解决方案一】每次都new新的控件视图。(缺点:这浪费你懂得)


【解决方案二】控件重用 通知刷新

点击checkBox时没必要一定要获取控件视图,并改变它。

可以在点击checkBox时,仅仅改变内部数据结构的内容。系统在显示控件时,会自动将item与控件绑定,至于重用了哪控件,不用你操心。我们只要做好绑定过程的 数据的填充 工作:用内部数据结构的内容去填充(更新)绑定的控件视图。


这样,当点击checkBox时,改变内部数据结构的内容,并通知刷新即可。

BaseExpandableListAdapter中的getGroupView如下:


ChildViewcheckBox OnCheckedChangedListener onChenckedChanged() 如下:


【解决方案三】控件重用 获取被绑定的控件

如果你硬是不想用 notifyDataSetChanged() 方法的话,就这样:


getChildAt()只能获取当前界面可见的视图。




猜你喜欢

转载自blog.csdn.net/zhoaya188/article/details/40317739