您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 经营企划 > AndroidListViewCheckBox状态错乱
listView中包含checkBox的时候,经常会发生其中的checkBox错乱的问题,大多时候的代码如下:先看一下效果图:奇数行为选中状态,偶数行为非选中状态具体代码:布局文件:1?xmlversion=1.0encoding=utf-8?2LinearLayoutxmlns:android=:layout_width=fill_parent4android:layout_height=fill_parent5android:orientation=horizontal67LinearLayout8android:id=@+id/layout9android:layout_width=fill_parent10android:layout_height=fill_parent1112TextView13android:id=@+id/textView14android:layout_width=wrap_content15android:layout_height=wrap_content/1617CheckBox18android:id=@+id/checkBox19android:layout_width=wrap_content20android:layout_height=wrap_content/2122/LinearLayout2324/LinearLayoutJAVACODE:1packagecom.tony.ui.listview;23importjava.util.ArrayList;4importjava.util.List;56importcom.tony.R;78importandroid.app.Activity;9importandroid.os.Bundle;10importandroid.view.LayoutInflater;11importandroid.view.View;12importandroid.view.ViewGroup;13importandroid.widget.BaseAdapter;14importandroid.widget.CheckBox;15importandroid.widget.CompoundButton;16importandroid.widget.CompoundButton.OnCheckedChangeListener;17importandroid.widget.LinearLayout;18importandroid.widget.ListView;19importandroid.widget.TextView;2021publicclassListViewCheckBoxextendsActivity{2223privateListViewlistView;24privateListAlist;25privateAdapter1adapter1;2627@Override28protectedvoidonCreate(BundlesavedInstanceState){29super.onCreate(savedInstanceState);30setContentView(R.layout.listview_checkbox);31initDate();32listView=(ListView)findViewById(R.id.listView);33adapter1=newAdapter1();34listView.setAdapter(adapter1);35}363738/**39*模拟40个数据,奇数数据为选中状态,偶数数据为非选中状态40*/41privatevoidinitDate(){42list=newArrayListA();43Aa;44for(inti=0;i40;i++){45if(i%2==0){46a=newA(i+号位,A.TYPE_NOCHECKED);47list.add(a);48}else{49a=newA(i+号位,A.TYPE_CHECKED);50list.add(a);51}52}53}5455classAdapter1extendsBaseAdapter{5657@Override58publicintgetCount(){59returnlist.size();60}6162@Override63publicObjectgetItem(intposition){64returnnull;65}6667@Override68publiclonggetItemId(intposition){69return0;70}7172@Override73publicViewgetView(intposition,ViewconvertView,ViewGroupparent){74finalintindex=position;75ViewHolderviewHolder;76if(convertView==null){77viewHolder=newViewHolder();78convertView=LayoutInflater.from(ListViewCheckBox.this).inflate(R.layout.listview_checkbox_item,null);79viewHolder.layout=(LinearLayout)convertView.findViewById(R.id.layout);80viewHolder.textView=(TextView)convertView.findViewById(R.id.textView);81viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox);82convertView.setTag(viewHolder);83}else{84viewHolder=(ViewHolder)convertView.getTag();85}868788viewHolder.textView.setText(list.get(position).name);89if(list.get(position).type==A.TYPE_CHECKED){90viewHolder.checkBox.setChecked(true);91}else{92viewHolder.checkBox.setChecked(false);93}9495/*点击checkBox所在行改变checkBox状态*/96/*finalViewHoldervv=viewHolder;97viewHolder.layout.setOnClickListener(newOnClickListener(){98@Override99publicvoidonClick(Viewv){100if(vv.checkBox.isChecked()){101vv.checkBox.setChecked(false);102list.get(index).type=TYPE_CHECKED;103}else{104vv.checkBox.setChecked(true);105list.get(index).type=TYPE_NOCHECKED;106}107108}109});*/110111viewHolder.checkBox.setOnCheckedChangeListener(newOnCheckedChangeListener(){112@Override113publicvoidonCheckedChanged(CompoundButtonbuttonView,booleanisChecked){114if(isChecked){115list.get(index).type=A.TYPE_CHECKED;116}else{117list.get(index).type=A.TYPE_NOCHECKED;118}119}120});121122returnconvertView;123}124}125126classViewHolder{127LinearLayoutlayout;128TextViewtextView;129CheckBoxcheckBox;130}131132classA{133134publicstaticfinalintTYPE_CHECKED=1;135publicstaticfinalintTYPE_NOCHECKED=0;136137Stringname;138inttype;139140publicA(Stringname,inttype){141this.name=name;142this.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(newOnCheckedChangeListener()...);这句话,就是给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对象在第一屏的时候需要显示成未选择状态,而到了第二屏的时候,却要显示成选择状态,但
本文标题:AndroidListViewCheckBox状态错乱
链接地址:https://www.777doc.com/doc-2897175 .html