本文可以帮助 完美解决在Android中使用ListView时批量操作CheckBox出现的各种问题。

在Android中使用ListActivity可以很方便的绑定一组数据或者一个查询。但是,使用过程中也会遇到一些问题。在此,我将自己遇到的问题以及解决方法记录下来,一方面做一个备忘,同时,也希望有缘人能少走弯路。


问题一: Listview中的Item数目到底是多少

ListView中的Item数目可以使用getCount方法获得,经过验证得到的结果是,其Item数目等于界面上显示的Item数目,这个数目可能小于实际上绑定的数据条目数。

那么,在实际中如果有额外的非绑定数据源的数据需要编辑保存的时候,如何才能保存他们呢?

解决该问题的方法是:自定义ListAdapter,在其中保存额外需要保存的数据。


问题二:在Item中添加CheckBox出现麻烦了

在item中添加Checkbox的时候不小心会遇到麻烦,可能出现的情况是:

(1)Listview不能相应点击事件

(2)Listview点击第一个Item的时候最后一个Item也出现点击事件(反之亦然)

以上两种情况是我实际遇到的bug,经过各种纠结和反复测试,出现问题的原因是CheckBox相应焦点、点击事件的优先级别比Listview要高,所以出现问题。

解决方法如下(和问题一一对应):

(1)将Checkbox设置focusable属性为false

(2)接着将CheckBox设置Clickable属性为false.

以下是本人程序片段,仅供参考:

<!-- ans_list.xml --><?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:paddingLeft="8dp"    android:paddingRight="8dp" >    <TextView        android:id="@+id/ans_title"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:gravity="center"        android:textSize="15sp"        android:textStyle="bold" />    <RelativeLayout        android:id="@+id/ans_foot"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:paddingLeft="8sp"        android:paddingRight="8sp" >        <CheckBox            android:id="@+id/ans_cbx_select"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_marginLeft="10sp"            android:checked="false" />        <Button            android:id="@+id/ans_btn_showInMap"            android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:layout_toLeftOf="@id/ans_cbx_select"            android:text="@string/ans_btn_showInMap" />    </RelativeLayout>    <ListView        android:id="@android:id/list"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:layout_above="@id/ans_foot"        android:layout_below="@id/ans_title"        android:drawSelectorOnTop="false" >    </ListView>    <TextView        android:id="@android:id/empty"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:gravity="center"        android:text="@string/ans_list_empty"        android:textSize="25sp"        android:textStyle="bold" >    </TextView></RelativeLayout>


<!-- ans_item.xml --><?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:padding="10sp" >    <CheckBox        android:id="@+id/ans_item_select"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:focusable="false"        android:clickable="false"        android:checked="false"        android:gravity="center_vertical" />    <RelativeLayout        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        >        ....        <TextView            android:id="@+id/ans_item_time"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_below="@id/ans_item_locname"            android:layout_toRightOf="@id/a4" />    </RelativeLayout></RelativeLayout>

   public class AnsList extends ListActivity {private PoiDbAdapter dba = null;private Cursor cursor = null;private ListView listView = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.ans_list);// 初始化标题...// 初始化列表initList();if (listView == null || listView.getCount() < 1) {findViewById(R.id.ans_foot).setVisibility(View.GONE);} else {initEvents();}}/** 初始化列表 */private void initList() {listView = getListView();dba = new PoiDbAdapter(this);cursor = dba.selectAnsByQnaire(QNaireBuilder.getQnaire(null).getQnaireId());startManagingCursor(cursor);        // 构造游标适配器MyCursorAdapter adapter = new MyCursorAdapter(this, R.layout.ans_item,cursor, new String[] { ARemoteId, ALongi, ALati, ALocName,ATime }, new int[] { R.id.ans_item_num,R.id.ans_item_longi, R.id.ans_item_lati,R.id.ans_item_locname, R.id.ans_item_time });// 自定义ViewBinder,日期类型的数据需要转换adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {public boolean setViewValue(View view, Cursor cursor,int columnIndex) {String text = cursor.getString(columnIndex);if (cursor.getColumnName(columnIndex).equalsIgnoreCase(ATime)) {text = TimeTools.formatTime(Long.valueOf(text));}if (view instanceof TextView) {((TextView) view).setText(text);}return true;}}); setListAdapter(adapter);}/** 为按钮和复选框添加事件处理, 为列表添加事件 */private void initEvents() {             ....((CheckBox) findViewById(R.id.ans_cbx_select)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {selectAllOrNot(isChecked);}});}.../** 全选或全部不选 */protected void selectAllOrNot(boolean isChecked) {int count = listView.getChildCount();for (int i = 0; i < count; i++) {((CheckBox) ((listView.getChildAt(i)).findViewById(R.id.ans_item_select))).setChecked(isChecked);}((MyCursorAdapter) listView.getAdapter()).selectAll(isChecked);}...@Overrideprotected void onListItemClick(ListView l, View v, int position, long id) {CheckBox cbx = (CheckBox) v.findViewById(R.id.ans_item_select);if (cbx != null) {cbx.toggle();((MyCursorAdapter) l.getAdapter()).select(position, cbx.isChecked());}}}

// 自定义ListAdapterpublic class MyCursorAdapter extends SimpleCursorAdapter {private HashMap<Integer, Boolean> isSelected = null;public MyCursorAdapter(Context context, int layout, Cursor c,String[] from, int[] to) {super(context, layout, c, from, to);isSelected = new HashMap<Integer, Boolean>();selectAll(false);}// ListView加载新的Item的时候会调用这个方法// 在加载前设置好意境保存好的Checkbox的状态@Overridepublic View getView(int position, View convertView, ViewGroup parent) {convertView = super.getView(position, convertView, parent);Boolean b = isSelected.get(position);if (null == b)b = false;if (convertView instanceof ViewGroup) {ViewGroup g = (ViewGroup) convertView;for (int i = 0; i < g.getChildCount(); i++) {View v = g.getChildAt(i);if (v instanceof CheckBox) {((CheckBox) v).setChecked(b);break;}}}return convertView;}public void select(int postion, boolean isChecked) {isSelected.put(postion, isChecked);}public void selectAll(boolean isChecked) {int a = this.getCount();for (int b = 0; b < a; b++) {select(b, isChecked);}}}


经过折腾之后,终于顺利通过调试,可以轻松实现全选批量操作,

运行效果如下:

解决 Android 中使用ListView和CheckBox批量操作时若干问题_第1张图片


@plusplus1




更多相关文章

  1. 【Android 开发】: Android客户端与服务端之间使用JSON交互数据
  2. Android之Android的数据存储--SD卡
  3. Android之View篇2————View的事件分发
  4. 深入Android【八】 —— Activity间数据传输
  5. 快速开发框架Afinal的使用(数据库操作,HTTP请求,网络图片加载,控件绑
  6. Android开发小记--开发实用工具类--数据库操作类
  7. 事件机制(2)--Android onTouchEvent, onClick及onLongClick的调用
  8. php实现post请求 接收android客户端json数据 存储数据库 并返回j

随机推荐

  1. Python Flask高级编程之从0到1开发《鱼书
  2. Kafka原理详解
  3. 【故障】win10系统使用打印功能就蓝屏
  4. MongoDB用户权限管理
  5. Clion激活码免费提取,更新于2021年3月15日
  6. Linux进程管理工具 Supervisor详解
  7. Python3高级核心技术97讲
  8. K8s-Pod生命周期
  9. Elasticsearch基本CURD操作
  10. Activiti6.0工作流引擎深度解析