控件视图重用,就是当convertView不为空的时候直接重新使用convertView从而减少了很多不必要的View的创建,然后加载数据。当列表往上下拖时,那些被拖出屏幕外的控件会重用。当触发器被触发时,触发该控件的OnCheckedChanged处理程序,而这个处理程序指向的数据项是前一次绑定的btnList中button的数据,这样就可能导致视图混乱。
【错误案例】:
(这里使用ExpandableListView expandableListView;Button在Group中,checkBox在child中,点击child的checkBox 会触发checkedChanged 操作,改变Group 的Button 的内容。)
BaseExpandableListAdapter中的getGroupView如下:
ChildView中checkBox 的OnCheckedChangedListener 的onChenckedChanged() 如下:
【错误案例演示】:
一开始生产所有Group时,btnList 中的0、1、2、3....分别与 group Item 的0、1、2、3...对应;
这时对btnList的0元素Button的操作,是没问题的:
但是,当第一个item的控件视图被移出当前界面时,后面新的item会将其利用起来,导致新的item莫名其妙地被改变了:
随着不断的上下翻动,item的控件视图将愈发混乱。
【解决方案一】:每次都new新的控件视图。(缺点:这浪费你懂得)
【解决方案二】:控件重用 + 通知刷新
点击checkBox时没必要一定要获取控件视图,并改变它。
可以在点击checkBox时,仅仅改变内部数据结构的内容。系统在显示控件时,会自动将item与控件绑定,至于重用了哪控件,不用你操心。我们只要做好绑定过程的 数据的填充 工作:用内部数据结构的内容去填充(更新)绑定的控件视图。
这样,当点击checkBox时,改变内部数据结构的内容,并通知刷新即可。
BaseExpandableListAdapter中的getGroupView如下:
ChildView中checkBox 的OnCheckedChangedListener 的onChenckedChanged() 如下:
【解决方案三】:控件重用 + 获取被绑定的控件
如果你硬是不想用 notifyDataSetChanged() 方法的话,就这样:
getChildAt()只能获取当前界面可见的视图。