




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
listView中包含checkBox的时候,经常会发生其中的checkBox错乱的问题,大多时候的代码如下:先看一下效果图:奇数行为选中状态,偶数行为非选中状态具体代码:布局文件: 1 2 6 7 11 12 16 17 21 22 23 24 JAVA CODE: 1 package com.tony.ui.listview; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import com.tony.R; 7 8 import android.app.Activity; 9 import android.os.Bundle; 10 import android.view.LayoutInflater; 11 import android.view.View; 12 import android.view.ViewGroup; 13 import android.widget.BaseAdapter; 14 import android.widget.CheckBox; 15 import android.widget.CompoundButton; 16 import android.widget.CompoundButton.OnCheckedChangeListener; 17 import android.widget.LinearLayout; 18 import android.widget.ListView; 19 import android.widget.TextView; 20 21 public class ListViewCheckBox extends Activity 22 23 private ListView listView; 24 private List list; 25 private Adapter1 adapter1; 26 27 Override 28 protected void onCreate(Bundle savedInstanceState) 29 super.onCreate(savedInstanceState); 30 setContentView(R.layout.listview_checkbox); 31 initDate(); 32 listView = (ListView)findViewById(R.id.listView); 33 adapter1 = new Adapter1(); 34 listView.setAdapter(adapter1); 35 36 37 38 /* 39 * 模拟40个数据,奇数数据为选中状态,偶数数据为非选中状态 40 */ 41 private void initDate() 42 list = new ArrayList(); 43 A a; 44 for(int i=0;i40;i+) 45 if(i%2=0) 46 a = new A(i+号位,A.TYPE_NOCHECKED); 47 list.add(a); 48 else 49 a = new A(i+号位,A.TYPE_CHECKED); 50 list.add(a); 51 52 53 54 55 class Adapter1 extends BaseAdapter 56 57 Override 58 public int getCount() 59 return list.size(); 60 61 62 Override 63 public Object getItem(int position) 64 return null; 65 66 67 Override 68 public long getItemId(int position) 69 return 0; 70 71 72 Override 73 public View getView(int position, View convertView, ViewGroup parent) 74 final int index = position; 75 ViewHolder viewHolder; 76 if(convertView = null) 77 viewHolder = new ViewHolder(); 78 convertView = LayoutInflater.from(ListViewCheckBox.this).inflate(R.layout.listview_checkbox_item, null); 79 viewHolder.layout = (LinearLayout)convertView.findViewById(R.id.layout); 80 viewHolder.textView = (TextView)convertView.findViewById(R.id.textView); 81 viewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.checkBox); 82 convertView.setTag(viewHolder); 83 else 84 viewHolder = (ViewHolder)convertView.getTag(); 85 86 87 88 viewHolder.textView.setText(list.get(position).name); 89 if(list.get(position).type = A.TYPE_CHECKED) 90 viewHolder.checkBox.setChecked(true); 91 else 92 viewHolder.checkBox.setChecked(false); 93 94 95 /*点击checkBox所在行改变checkBox状态*/ 96 /*final ViewHolder vv = viewHolder; 97 viewHolder.layout.setOnClickListener(new OnClickListener() 98 Override 99 public void onClick(View v) 100 if(vv.checkBox.isChecked()101 vv.checkBox.setChecked(false);102 list.get(index).type = TYPE_CHECKED;103 else104 vv.checkBox.setChecked(true);105 list.get(index).type = TYPE_NOCHECKED;106 107 108 109 );*/110 111 viewHolder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() 112 Override113 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 114 if(isChecked)115 list.get(index).type = A.TYPE_CHECKED;116 else117 list.get(index).type = A.TYPE_NOCHECKED;118 119 120 );121 122 return convertView;123 124 125 126 class ViewHolder127 LinearLayout layout;128 TextView textView;129 CheckBox checkBox;130 131 132 class A 133 134 public static final int TYPE_CHECKED = 1;135 public static final int TYPE_NOCHECKED = 0;136 137 String name;138 int type;139 140 public A(String name,int type)141 = name;142 this.type = type;143 144 145 以上代码就是根据List集合中的对象的类型来设置checkBox是否为选中状态,当用户点击checkBox的时候,程序根据checkBox是否选中来将其状态保存至list集合对象中,相信很多人第一次做的时候会信心满满地认为这样的逻辑简直天衣无缝。但结果是,测试的时候还没有点击checkBox来改变其状态,只是简单地上下拉动listView的时候就会发现,好像事情没有想象的那么简单。效果图如下:只要视力不算太差的人便一眼可以看出,按照程序的逻辑怎么连续两个checkBox的状态会一样呢,恩,肯定是模拟器神经错乱了。解决方案:很多人给出的两种解决办法1:上来就说是因为convertview对象共用的原因,不能用convetView,而是每次getView()的时候都new一个对象的view出来.这种办法大概是用屁股想出来的.2:即然错乱,那我就自己再弄一个集合保存checkBox的状态,再错乱,弄死你.即然adapter里有一个list集合里保存checkBox的状态了,为什么还要自己再保存一次checkBox的状态呢,不是多此一举吗?PS:提供这两种办法的人都没有解释到底是为什么错乱.下面来尝试分析一下:1:首先分析下viewHolder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener().); 这句话,就是给checkBox添加一个监听器,如果checkBox的状态改变了,那么系统就会自动回调里面的onCheckedChange()方法. 而文中onCheckedChange()方法里写的是记录这次改变后checkBox状态的代码.2:再接着分析下if(list.get(position).type = A.TYPE_CHECKED).,这部分代码是根据list集合里的对象属性初始化view里checkBox是否应该是选择状态.3:我上下滑动listView的时候,checkBox的状态就错乱了,根据第二点的分析,无论如何checkBox的状态都不会错乱,除非list集合里对象的属性已经被改变了,到底是什么地方改变了它?4:文中只有一个地方写了改变list集合里checkBox对象属性的地方,那就是第一点里提到的OnCheckedChangeListener()方法。它被执行了?怎么回事,不可能吧,打个断点,跑一下便知上下滑动listView的时候确实停了下来.5:这便是convertView的功能,因为不管listView里显示多少条数据,都只是共用那么几个对象,然后我们的代码每一次把得到的对象重新赋值而已。对了,正是在这赋值的时候出了问题,假设android系统给我们生成了10个共用view对象,第一个view对象在第一屏的时候需要显示成未选择状态,而到了第二屏的时候,却要显示成选择状态,但由于是共用的同一个对象,根据第一点得知当checkBox的状态改变的时候,会调用onCheckedChange()方法。6:也许有人会怀疑就算它调用了onCheckedChanged()方法,那又如何?onCheckedChange()方法里的代码还是将当前是否为选中状态保存到了list集合里,当我再次显示时还是会根据第二点里提到的代码来正确地显示,是的,代码会根据当前index来改变list集体的属性.关键就在这里,这个index真的是对的吗?测试一下便知:在onCheckedChange()方法里打印一下index,当快速向下滑动的时候,index的值如下: 7:共用的对象有10(这里举例,并不是一定)个,当onCheckedChange()方法调用的时候,至少也是共用对象用光的时候,再从第一个共用对象用的时候才会打印,那时的index也应该是从10开始,为什么打印的结果里会出现0?8:这是由于代码的顺序决定的,根据上面的代码可以看出,添加监听器的代码在初始化checkBox属性的代码之后,也就是说当初始化checkBox属性时,由于可能改变其状态,导致调用了onCheckedChange()方法,而这个监听器是在上一次初始化的时候添加的,那么当然其index就是上一次的positon值,而不是本次的,所以每次保存checkBox属性状态的时候,都把值赋到的list集合里其它对象上去了,而不是与本次index相关的对象上,这才是发生莫名其妙错乱的真正原因.9:解决办法:由于是因为index错误造成的,那么只要保证index值与当前positon保持一至即可,只要把添加监听器的方法加到初始化view中checkBox状态的代码之前即可.这样即始由于初始化造成调用了onCheckedChange()方法,也因为其中index值是最新的,而依然不会错乱.代码示例: 1 class Adapter1 extends BaseAdapter 2 3 Override 4 public int getCount() 5 return list.size(); 6 7 8 Override 9 public Object getItem(int position) 10 return null;11 12 13 Override14 public long getItemId(int position) 15 return 0;16 17 18 Override19 public View getView(int position, View convertView, ViewGroup parent) 20 final int index = position;21 ViewHolder viewHolder;22 if(convertView = null)23 viewHolder = new ViewHolder();24 convertView = LayoutInflater.from(ListViewCheckBox.this).inflate(R.layout.listview_checkbox_item, null);25 viewHolder.layout = (LinearLayout)convertView.findViewById(R.id.layout);26 viewHolder.textView = (TextView)convertView.findViewById(R.id.t
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 大专工商企业管理学什么
- 教师个人教学教研工作总结
- 绿化春季种植培训课件
- 美食城培训课件
- 重症喘息性肺炎诊疗规范
- 监理资料培训讲义
- 建议类考试题及答案
- 肩颈考试题及答案
- 驾驶知识考试题及答案
- 新初一课程培训
- 国开2024年《JavaScript程序设计》形考1-3答案
- 《人工智能基础概念》考试复习题库(浓缩300题)
- 端子压接技术标准
- 消费经济学完整整套教学课件
- 机械特性测试仪操作规程
- 超星学习通艺术美学(苏州大学)章节答案
- 护理查房高位截瘫584
- GA 1524-2018射钉器公共安全要求
- 植物学第三小组名录
- 2023年赣南师范大学科技学院辅导员招聘考试笔试题库及答案解析
- 电脑的认识 完整版课件
评论
0/150
提交评论