在Android开发中经常遇到ListView的条目中有CheckBox的问题,在这里为几个常遇到的问题提供一些粗略的解决方法
问题一:出现混乱
在开发中ListVeiw的条目中直接加入CheckBox
1.activity_main.xml的布局文件内容
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/activity_main" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
2.item_view.xml的布局内容
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!--android:descendantFocusability="blocksDescendants"-->
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:padding="5dp"
android:text="中国"/>
<CheckBox
android:id="@+id/ck_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"/>
</RelativeLayout>
3.Adapter中的getView()方法的内容
if (convertView == null){
convertView = View.inflate(mContext , R.layout.item_view , null);
}
TextView tvTitle = (TextView) convertView.findViewById(R.id.tv_title);
tvTitle.setText(mTitles[position]);
return convertView;
在第一屏选中一个CheckBox以后,当滚动listview时,发现出现混乱,原因是converview复用导致的。
解决办法
- 在Adapter中使用Map集合存储position下标, 与checkBox 选中形成对应关系, 在getView方法里面, 对每一个position在进行判定,拿position去map集合里面判断,有没有这条记录,如果有,那么表明曾经有选中这个checkBox ,那么现在就让它选中,否则表明以前不选中,现在也不能选中。
SparseBooleanArray array = = new SparseBooleanArray();
<------------------------------------------------>
private void initMapData() {
for (int i = 0; i < mTitles.length; i++) {
array.append(i , false);
}
}
- 跟item数据对象绑定上。 在javaBean里面添加一个属性 boolean isCheck , 谁勾选了,我就让谁的这个属性 = true , 谁要是取消了,我就让谁的这个属性 =false
问题二:焦点和点击事件问题
1, 没有设置CheckBox没有焦点和不可点击,那么CheckBox可以点击和拿到焦点,但是这样ListView的条目点击事件将失去作用,如果想通过条目点击事件修改checkbox是否选中,首先需要将checkbox设置为没有焦点和不可点击
//checkbox设置为没有焦点和不可点击
android:focusable="false"
android:clickable="false"
2.在adapte中暴露两个方法,根据position获取当前的checkbox是否选中和进行是否选中的更改,在onItemOnClickListener中就可以调用这两个方法进行选中状态的修改
/**
* 更改是否选中
* @param position
* @param isCheck
*/
public void upIsCheck(int position , boolean isCheck){
array.put(position , isCheck);
/*ListCBBean bean = mBeans.get(position);
bean.isCheck = isCheck;
array.put(position , isCheck);*/
}
/**
* 根据position获取是否选中
* @param position
* @return
*/
public boolean getIsCheck(int position){
return array.get(position);
/*ListCBBean bean = mBeans.get(position);
return bean.isCheck;*/
}
问题三:checkBox和条目点击事件都起作用
只需要在item_view.xml的跟标签中加入如下属性就可以
android:descendantFocusability="blocksDescendants