ListView 中CheckBox与RadioButton的状态解决方法
来源:互联网 发布:域名跳转到淘宝店铺 编辑:程序博客网 时间:2024/05/20 07:51
没想到,生产一辆跑车,车轮上的螺丝出问题就得花去一定时间。ListView就是这款螺丝,也不知道Android的开发人员是怎么的,这个破ListView竟然折磨了开发人员很久,而且还是在一些基础的控件RadioButton(rb)与CheckBox(cb)的状态使用上,太抓狂,现象如下:
现象一:listview放置rb后onItemClickListener事件失效;
现象二:listview 放置rb或cb后,用户希望在点击listview中的整条item时,就能变更rb/cb状态,但实际上,用户必须点击到rb/cb后才选中。
现象三:cb(checkbox) 滚动状态丢失现象: listview 中,如果有10项,其中手机屏幕显示1-6项,其余的7-10项在屏幕中不可见,得向下滚动后才能看到,这个时候,如果选中1、2项,再滚动到7-10项,之后再滚动回来1-6项,就发现1、2项并未被选中。(其现象和asp.net中翻页后丢失item的checkbox状态丢失现象是一样)
现象四:rb单选功能失效:listview中的单选按钮如果不进行处理,是不可能实现单选功能,而且,现象三的情况也会出现在这里。
以上这四种现象,哪怕是一种,都足够折磨人的了,现象一、二解决方法如下:
现象一:在listview 中rb对象XML属性中(cb同理),增加:android:focusable="false" android:focusableInTouchMode="false",因为rb的焦点是先于listview的,所以,设置屏蔽后,listview事件才能触发
现象二:修改listview每个条目所需要用的View项对应的xml文件(如rowitem.xml),在LinearLayout对象中,增加: android:descendantFocusability="blocksDescendants"
<!--现象一、二解决方法--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/row_checkbox_item" android:layout_width="fill_parent" android:layout_height="fill_parent" android:descendantFocusability="blocksDescendants" <!-- 务必设置descendantFocusability项 --> android:orientation="horizontal" > <TextView android:id="@+id/row_checkbox_title" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <CheckBox android:id="@+id/row_checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="4dp" android:layout_marginRight="10dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:clickable="false"<!-- 设置clickable不可选--> android:focusable="false"<!-- 设置foucusable失去焦点--> android:focusableInTouchMode="false" /><!-- 设置foucsableInTouchMode失去焦点(点击模式) --> <RadioButton android:id="@+id/rbtn_phone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false"<!-- 设置clickable不可选--> android:focusable="false"<!-- 设置foucusable失去焦点 --> android:focusableInTouchMode="false"/><!-- 设置foucsableInTouchMode失去焦点(点击模式)--> </LinearLayout>
这样,就可以通过修改xml布局文件来初步达到rb和cb的选中和事件触发问题,接下来解决另外两个问题。
现象三解决办法:
产生原因:每个item对应一个view,每个view中,可以有rb/cb/txtview等子view控件。listview在滚动时,会重新对每个进入屏幕的item项(view)进行数据载入(可以理解为网页上的翻页,屏幕滚动时,就是翻页),譬如,listview有10条item,,屏幕每次只能显示5条,开始时1-5条显示在屏幕上,另外5条在屏幕外,向下滚动到第7条后,第1-2条item从屏幕消失,第6-7条item显示在屏幕上,此时,listview会重新对6-7条进行数据载入,对于1-2条的item,listview一点也不为他们保留任何状态,所以,现象就产生了。
另外,滚动屏幕后,譬如,屏幕从1-5条滚动到6-10条,1-5条在屏幕外,第6条在屏幕最顶端,此时如果尝试使用parent.getChildAt(6)访问屏幕顶端的第6条item时,你会发现,会返回null,包括7-10条,都是返回null,但是,getChildAt(0)时却能返回一个对象,原来,系统为了节约资源,会用之前第0项来初始化滚屏后的第6条,而不是重新创建一个item对象(其对应关系一次类推),所以为什么会返回null,就是这个原因,一不留意,极容易产生异常。
如果对于cb来说,要实现多选 解决办法就是,建立一个List对象,将选中的item对应的状态保存到List中,List下标即是item在listview中的位置position),而值则是cb的状态标志(true/false)。通过重载getview方法实现。代码如下:
使用ArrayAdapter为例子:
public class CustomizedAdapter extends ArrayAdapter<List>{static int selectitem=-1; //用于记录单选rb的最新选中位置 private LayoutInflater inflater;private Context context;private List list;public CustomizedAdapter(Context context, List listitem){super(context, R.layout.rowcheckoutlist, listitem);this.context=context;this.list=listitem;inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn this.list.size();}@Overridepublic ArrayList getItem(int position) {// TODO Auto-generated method stubreturn (ArrayList) this.list.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stub//pos必须声明为final,如果声明成普通类型,那么每次触发cb事件时pos永为0,final int pos = position;View rowView = (View)convertView;//如果rowView为空时,必须实例化一个xml,if (rowView==null){rowView = inflater.inflate(R.layout.rowcheckoutlist, null, true);}CheckBox cb= (CheckBox) rowView.findViewById(R.id.row_checkbox);cb.setTag("tagCheckBox");//为每个cb设置监听,当cb状态改变时,保存cb状态到list中,pos是当前listview中cb的位置,//譬如,用户点击第二个cb,那么pos的值为2cb.setOnCheckedChangeListener(new OnCheckedChangeListener(){@Overridepublic void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {//保存checked状态到list对应的位置中list.set(pos, isChecked);}});cb.setChecked((Boolean) list.get(pos));//处理radioButtonRadioButton rb = (RadioButton) rowView.findViewById(R.id.rbtn_phone); rb.setTag("tabRadioButton");//为每个rb设置监听,当前rb选择,保存当前rb对应的pos值到selecteitem(static类型),//譬如,用户点击第一个rb,那么selectitem为1,当再点击第二个rb时,//selectitem则为2,selectitem永远保存最后单击的rb的位置 rb.setOnCheckedChangeListener(new OnCheckedChangeListener(){ @Override public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) { if (isChecked) { selectitem = pos; } }}); if (pos == selectitem) rb.setChecked(true); else rb.setChecked(false);return rowView;}}
主函数:
@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);this.setContentView(R.layout.main);myListView = (ListView) this.findViewById(R.id.listView1);//新建一个List,用于保存cb的状态final List listitem = new ArrayList();for (int i=0;i<list.size();i++) {//初始化list, listitem.add(i,false); }CustomizedAdapter adapter = new CustomizedAdapter(this,listitem); myListView.setAdapter(adapter);//现象四rb解决方法://设置listview监听事件,该事件主要处理rb的单击时,将屏幕中所有rb状态//设置为false,再将当前rb设置成true,完成单选功能myListView.setOnItemClickListener(new setOnItemClickListener(){@Override public void onItemClick(AdapterView<?> parent, View convertView, int position,long id) {//遍历当前Item,设置所有Item的cb状态为falsefor(int i=0;i<parent.getCount();i++) { View childView = parent.getChildAt(i); if (childView==null) break; RadioButton mRadioButton = (RadioButton) childView.findViewById(R.id.rbtn_phone); mRadioButton.setChecked(false); }//设置选中rb状态为true;RadioButton rb = (RadioButton) convertView.findViewById(R.id.rbtn_phone);rb.setChecked(true);});}
通过以上方法,彻底解决listview的checkbox和radiobox的单、多选问题。如果有更好方法,欢迎交流
部分参考:http://blog.csdn.net/pathuang68/article/details/6455925
- ListView 中CheckBox与RadioButton的状态解决方法
- Android ListView加入CheckBox/RadioButton选择状态保持、全选、反选的状态
- Android ListView 中加入CheckBox/RadioButton 选择状态保持、全选、反选实现
- listview 与 radiobutton 滚动状态 保留radiobutton状态的完美解决办法
- RadioButton与CheckBox的区别
- CheckBox与RadioButton的使用
- RadioButton与 checkBox的使用
- listview中checkbox状态保存
- android中RadioButton与CheckBox小结
- listview中的checkbox状态保存与恢复的完美方法
- android开发--listview中checkbox的选中状态
- Android ListView/GridView的item中 CheckBox状态错乱
- android ListView 中CheckBox选中后,状态混乱的解决方案
- 关于ListView中checkBox选中状态错乱问题的解决办法
- 【listview&checkbox】listview中有checkbox 滑动后状态改变
- ListView中CheckBox的获取焦点冲突解决方法
- 兔子--CheckBox与Radiobutton的区别
- android中checkbox和radiobutton的使用
- Jquery Mobile总结
- 切换样式表
- objdump的使用方法
- 全国软件设计大赛题目-逻辑推断题目
- CLP考试-管理520试题.doc
- ListView 中CheckBox与RadioButton的状态解决方法
- FreeBSD 8 Warning: syntax error on file /boot/loader.conf
- SQL Server 对XML数据类型的SQL语句总结
- Linux下源码编译安装MySQL 5.5.8
- 如何在ArcGIS Online中构建自己的应用程序模板初级篇-显示地图
- CLP考试-管理521试题.doc
- session.merge()方法
- 奇奇和小猫的故事
- 【MS】关于数据库死锁的解读