`
bcyy
  • 浏览: 1829808 次
文章分类
社区版块
存档分类
最新评论

解决 Android 中使用ListView和CheckBox批量操作时若干问题

 
阅读更多

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

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

  1. <!--ans_list.xml-->
  2. <?xmlversion="1.0"encoding="utf-8"?>
  3. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:paddingLeft="8dp"
  7. android:paddingRight="8dp">
  8. <TextView
  9. android:id="@+id/ans_title"
  10. android:layout_width="fill_parent"
  11. android:layout_height="wrap_content"
  12. android:layout_alignParentTop="true"
  13. android:gravity="center"
  14. android:textSize="15sp"
  15. android:textStyle="bold"/>
  16. <RelativeLayout
  17. android:id="@+id/ans_foot"
  18. android:layout_width="fill_parent"
  19. android:layout_height="wrap_content"
  20. android:layout_alignParentBottom="true"
  21. android:paddingLeft="8sp"
  22. android:paddingRight="8sp">
  23. <CheckBox
  24. android:id="@+id/ans_cbx_select"
  25. android:layout_width="wrap_content"
  26. android:layout_height="wrap_content"
  27. android:layout_alignParentRight="true"
  28. android:layout_marginLeft="10sp"
  29. android:checked="false"/>
  30. <Button
  31. android:id="@+id/ans_btn_showInMap"
  32. android:layout_width="fill_parent"
  33. android:layout_height="wrap_content"
  34. android:layout_toLeftOf="@id/ans_cbx_select"
  35. android:text="@string/ans_btn_showInMap"/>
  36. </RelativeLayout>
  37. <ListView
  38. android:id="@android:id/list"
  39. android:layout_width="fill_parent"
  40. android:layout_height="fill_parent"
  41. android:layout_above="@id/ans_foot"
  42. android:layout_below="@id/ans_title"
  43. android:drawSelectorOnTop="false">
  44. </ListView>
  45. <TextView
  46. android:id="@android:id/empty"
  47. android:layout_width="fill_parent"
  48. android:layout_height="fill_parent"
  49. android:gravity="center"
  50. android:text="@string/ans_list_empty"
  51. android:textSize="25sp"
  52. android:textStyle="bold">
  53. </TextView>
  54. </RelativeLayout>
    1. <!--ans_item.xml-->
    2. <?xmlversion="1.0"encoding="utf-8"?>
    3. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    4. android:layout_width="fill_parent"
    5. android:layout_height="wrap_content"
    6. android:padding="10sp">
    7. <CheckBox
    8. android:id="@+id/ans_item_select"
    9. android:layout_width="wrap_content"
    10. android:layout_height="wrap_content"
    11. android:layout_alignParentRight="true"
    12. android:focusable="false"
    13. android:clickable="false"
    14. android:checked="false"
    15. android:gravity="center_vertical"/>
    16. <RelativeLayout
    17. android:layout_width="fill_parent"
    18. android:layout_height="wrap_content"
    19. android:layout_alignParentLeft="true"
    20. >
    21. ....
    22. <TextView
    23. android:id="@+id/ans_item_time"
    24. android:layout_width="wrap_content"
    25. android:layout_height="wrap_content"
    26. android:layout_below="@id/ans_item_locname"
    27. android:layout_toRightOf="@id/a4"/>
    28. </RelativeLayout>
    29. </RelativeLayout>

    1. publicclassAnsListextendsListActivity{
    2. privatePoiDbAdapterdba=null;
    3. privateCursorcursor=null;
    4. privateListViewlistView=null;
    5. @Override
    6. protectedvoidonCreate(BundlesavedInstanceState){
    7. super.onCreate(savedInstanceState);
    8. setContentView(R.layout.ans_list);
    9. //初始化标题
    10. ...
    11. //初始化列表
    12. initList();
    13. if(listView==null||listView.getCount()<1){
    14. findViewById(R.id.ans_foot).setVisibility(View.GONE);
    15. }else{
    16. initEvents();
    17. }
    18. }
    19. /**初始化列表*/
    20. privatevoidinitList(){
    21. listView=getListView();
    22. dba=newPoiDbAdapter(this);
    23. cursor=dba.selectAnsByQnaire(QNaireBuilder.getQnaire(null)
    24. .getQnaireId());
    25. startManagingCursor(cursor);
    26. //构造游标适配器
    27. MyCursorAdapteradapter=newMyCursorAdapter(this,R.layout.ans_item,
    28. cursor,newString[]{ARemoteId,ALongi,ALati,ALocName,
    29. ATime},newint[]{R.id.ans_item_num,
    30. R.id.ans_item_longi,R.id.ans_item_lati,
    31. R.id.ans_item_locname,R.id.ans_item_time});
    32. //自定义ViewBinder,日期类型的数据需要转换
    33. adapter.setViewBinder(newSimpleCursorAdapter.ViewBinder(){
    34. publicbooleansetViewValue(Viewview,Cursorcursor,
    35. intcolumnIndex){
    36. Stringtext=cursor.getString(columnIndex);
    37. if(cursor.getColumnName(columnIndex).equalsIgnoreCase(ATime)){
    38. text=TimeTools.formatTime(Long.valueOf(text));
    39. }
    40. if(viewinstanceofTextView){
    41. ((TextView)view).setText(text);
    42. }
    43. returntrue;
    44. }
    45. });
    46. setListAdapter(adapter);
    47. }
    48. /**为按钮和复选框添加事件处理,为列表添加事件*/
    49. privatevoidinitEvents(){
    50. ....
    51. ((CheckBox)findViewById(R.id.ans_cbx_select))
    52. .setOnCheckedChangeListener(newCompoundButton.OnCheckedChangeListener(){
    53. @Override
    54. publicvoidonCheckedChanged(CompoundButtonbuttonView,
    55. booleanisChecked){
    56. selectAllOrNot(isChecked);
    57. }
    58. });
    59. }
    60. ...
    61. /**全选或全部不选*/
    62. protectedvoidselectAllOrNot(booleanisChecked){
    63. intcount=listView.getChildCount();
    64. for(inti=0;i<count;i++){
    65. ((CheckBox)((listView.getChildAt(i))
    66. .findViewById(R.id.ans_item_select))).setChecked(isChecked);
    67. }
    68. ((MyCursorAdapter)listView.getAdapter()).selectAll(isChecked);
    69. }
    70. ...
    71. @Override
    72. protectedvoidonListItemClick(ListViewl,Viewv,intposition,longid){
    73. CheckBoxcbx=(CheckBox)v.findViewById(R.id.ans_item_select);
    74. if(cbx!=null){
    75. cbx.toggle();
    76. ((MyCursorAdapter)l.getAdapter())
    77. .select(position,cbx.isChecked());
    78. }
    79. }
    80. }


    1. //自定义ListAdapter
    2. publicclassMyCursorAdapterextendsSimpleCursorAdapter{
    3. privateHashMap<Integer,Boolean>isSelected=null;
    4. publicMyCursorAdapter(Contextcontext,intlayout,Cursorc,
    5. String[]from,int[]to){
    6. super(context,layout,c,from,to);
    7. isSelected=newHashMap<Integer,Boolean>();
    8. selectAll(false);
    9. }
    10. //ListView加载新的Item的时候会调用这个方法
    11. //在加载前设置好意境保存好的Checkbox的状态
    12. @Override
    13. publicViewgetView(intposition,ViewconvertView,ViewGroupparent){
    14. convertView=super.getView(position,convertView,parent);
    15. Booleanb=isSelected.get(position);
    16. if(null==b)
    17. b=false;
    18. if(convertViewinstanceofViewGroup){
    19. ViewGroupg=(ViewGroup)convertView;
    20. for(inti=0;i<g.getChildCount();i++){
    21. Viewv=g.getChildAt(i);
    22. if(vinstanceofCheckBox){
    23. ((CheckBox)v).setChecked(b);
    24. break;
    25. }
    26. }
    27. }
    28. returnconvertView;
    29. }
    30. publicvoidselect(intpostion,booleanisChecked){
    31. isSelected.put(postion,isChecked);
    32. }
    33. publicvoidselectAll(booleanisChecked){
    34. inta=this.getCount();
    35. for(intb=0;b<a;b++){
    36. select(b,isChecked);
    37. }
    38. }
    39. }

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



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics