ListView + CheckBox(或者是RadioGroup等控件)的混乱选中原理
来源:互联网 发布:南京大学网络教育2017 编辑:程序博客网 时间:2024/05/21 08:54
1,常用的写法,只展示Adapter,问题原因就在Adapter中
class Adapter1 extends BaseAdapter{ @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { final int index = position; ViewHolder viewHolder; if(convertView == null){ viewHolder = new ViewHolder(); convertView = LayoutInflater.from(ListViewCheckBox.this).inflate(R.layout.listview_checkbox_item, null); viewHolder.layout = (LinearLayout)convertView.findViewById(R.id.layout); viewHolder.textView = (TextView)convertView.findViewById(R.id.textView); viewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.checkBox); convertView.setTag(viewHolder); }else{ viewHolder = (ViewHolder)convertView.getTag(); } viewHolder.textView.setText(list.get(position).name); if(list.get(position).type == A.TYPE_CHECKED){ viewHolder.checkBox.setChecked(true); }else{ viewHolder.checkBox.setChecked(false); } /*点击checkBox所在行改变checkBox状态*/ /*final ViewHolder vv = viewHolder; viewHolder.layout.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(vv.checkBox.isChecked()){ vv.checkBox.setChecked(false); list.get(index).type = TYPE_CHECKED; }else{ vv.checkBox.setChecked(true); list.get(index).type = TYPE_NOCHECKED; } } });*/ viewHolder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(isChecked){ list.get(index).type = A.TYPE_CHECKED; }else{ list.get(index).type = A.TYPE_NOCHECKED; } } }); return convertView; } } class ViewHolder{ LinearLayout layout; TextView textView; CheckBox checkBox; } class A { public static final int TYPE_CHECKED = 1; public static final int TYPE_NOCHECKED = 0; String name; int type; public A(String name,int type){ this.name = name; this.type = type; } }}
这时出现了混乱选中问题,为什么呢?
首先,我们使用了一个数组来存储每个CheckBox的状态,如果被选中,我们在setOnCheckedChangeListener 监听事件中的OnCheckChanged()方法中将状态修改为被选中,如果被取消选中,则改为被取消选中。
我们还使用了Convertview + ViewHolder来进行view的复用,提高listView的加载效率以及减少每次new一个View 的开销。这也是导致我们出现了混乱选中的根源所在。
下面来分析下到底是如何出现的混乱选中。
1,假设我们的convertview有着10个复用的View对象(这个好像会跟显示View时,一个屏幕能放下多少View相关,如果最多只能显示五个,那么只使用5个用来复用的View),那么当我们分别用完了这十个之后就会开始复用,比如说我的界面中有30个用ListView+CheckBox组成的选择题。
我们从其他地方点进ListView所在的Activity,ListView进行加载,那么前10个是没有问题的。假设第一个我们进行了选择,状态为Checked。当我们下滑,显示到第11个的时候,这个时候第11个viewItem会复用第一个item的View。
这时。当将这一个viewItem加载到ListView的第11个位置时,它的状态是Checked。通过从状态数组中读取第11个Item的选中状态时,发现我并没有选中第11个Item,这时就会将第11个Item设置为未选中。
一切看起来这么顺利!!!
但是!
当我们的第11个Item从复用的第一个ItemView的选中状态 到 从状态数组中读取的未选中状态,是经过了一次setOnCheckedChangeListener 选中变化事件的监听的。
而且!!
我们仔细看,我们的setOnCheckedChangeListener 监听事件的设置是写在了我们初始化item的选中状态之后的。
也就是说!!
这时候我们的setOnCheckedChangeListener 监听事件是在第一个ViewItem初始化时设置的那个监听事件。
这个时候,由于发生了选中状态的变化,由第一个Item的选中变化监听事件所监听到了,从而改变了第一个Item的状态。当滑动几次时,由于反复的在复用convertView,便出现了非常令人头疼的混乱选中。。!
解决办法:把添加监听器的方法加到初始化view中checkBox状态的代码之前即可
。这时监听器便不会混乱监听了。
完美~~~
class Adapter1 extends BaseAdapter{ @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { final int index = position; ViewHolder viewHolder; if(convertView == null){ viewHolder = new ViewHolder(); convertView = LayoutInflater.from(ListViewCheckBox.this).inflate(R.layout.listview_checkbox_item, null); viewHolder.layout = (LinearLayout)convertView.findViewById(R.id.layout); viewHolder.textView = (TextView)convertView.findViewById(R.id.textView); viewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.checkBox); convertView.setTag(viewHolder); }else{ viewHolder = (ViewHolder)convertView.getTag(); } viewHolder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(isChecked){ list.get(index).type = A.TYPE_CHECKED; }else{ list.get(index).type = A.TYPE_NOCHECKED; } } }); viewHolder.textView.setText(list.get(position).name); if(list.get(position).type == A.TYPE_CHECKED){ viewHolder.checkBox.setChecked(true); }else{ viewHolder.checkBox.setChecked(false); } return convertView; } }
- ListView + CheckBox(或者是RadioGroup等控件)的混乱选中原理
- ListView可回收引起CheckBox选中状态混乱的解决方案
- android ListView 中CheckBox选中后,状态混乱的解决方案
- Android ListView中使用CheckBox等的混乱问题
- Android ListView中的项中包含RadioGroup时,RadioButton混乱选中的问题的解决方法
- ListView中含有CheckBox或者Button等控件,导致item点击无效的原因。
- Android中ListView、GridView里的CheckBox混乱且记录选中数量不准确的解决方案
- 代码控制CheckBox或者其他控件的选中状态
- ListView和CheckBox的混乱问题
- ListView和CheckBox的混乱问题
- ListView和CheckBox的混乱问题
- Android开发:在ListView中使用RadioGroup时出现混乱选中现象
- Android开发:在ListView中使用RadioGroup时出现混乱选中现象
- Android开发:在ListView中使用RadioGroup时出现混乱选中现象
- 控件RadioGroup、RadioButton和CheckBox的使用
- RadioGroup,RadioButton CheckBox控件的使用
- Android-基本控件(CheckBox,RadioGroup,RadioButton)
- android listview中放radiogroup选择混乱
- mysql执行sql文件中文乱码解决
- 写入、读取Mysql数据库时乱码的解决办法:(超有效)
- spring mvc 注解RequestParam,RequestBody,ModelAttribute详细说明
- 免费的STUN服务器
- Java设计模式之创建型模式-原型模式(Prototype)
- ListView + CheckBox(或者是RadioGroup等控件)的混乱选中原理
- HDU 6170 Two strings (二维DP)
- springmvc集成shiro后,session、request姓什么?
- python2/3---sort方法与sorted函数的使用
- Android 监听软键盘弹出
- Xor Sum Gym
- Windows Practice_文件搜索器(四)_封装文件扫描器
- Gym
- Codeforces 845 C Two TVs