本文可以帮助 完美解决在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);}}}


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

运行效果如下:



@plusplus1




更多相关文章

  1. 移植 android, touch screen 不能正常工作的问题
  2. Android(安卓)RSA与Java RSA加密不同标准产生问题的解决方法
  3. Android应用如何支持屏幕多尺寸多分辨率问题
  4. android 关于appcompat v7出错问题与解决
  5. 学习android的一些套路(转发之小黑屋总结)
  6. Android(安卓)setTag方法的key问题
  7. android差分更新之服务端
  8. android 使用socket与pc传递对象的问题
  9. Android(安卓)Cannas.drawTextView 方法坐标问题

随机推荐

  1. Android(安卓)穿山甲广告接入注意事项
  2. android eclipse 报error loading /syste
  3. 【Android】从无到有:手把手一步步教你构
  4. Android(安卓)studio 一直卡在Gradle:Bui
  5. android SharedPreferences 记录数据
  6. Android(安卓)ApiDemos示例解析
  7. Android官方下拉刷新控件 SwipeRefreshLa
  8. Android(安卓)开发第四天
  9. Firebase Crashlytics Sdk接入流程(Androi
  10. Android(安卓)在低版本sdk中没有getSuppo