转自:http://yangshen998.iteye.com/blog/1310183

在Android某些开发需求当中,有时候需要在listveiw中加入checkbox实现单选,多选操作。表面上看上去只是改变checkbox那么简单,然而实际开发中,实现起来并不是那么得心应手。尤其当listview比较多(比如屏幕最多只能显示10个item,但总共有12个item,也就是说listview的item数大于屏幕能够显示的item数)滑动屏幕的时候,由于适配器中getview()会重复使用被移除屏幕的item,所以会造成checkbox选择状态不正常的现象。自己在开发中碰到这样的问题很是苦恼,查了下资料,发现网上很少没有针对这类批量操作并没有一个完整的例子。搜了很多篇帖子才完美的实现这一常用的操作。所以在这里把这个Demo贴出来,供大家参考,希望能对大家有所帮助。

主界面的布局main.xml 这个就不多说什么

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="wrap_content"
  5. android:orientation="vertical" >
  6. <LinearLayout
  7. android:orientation="vertical"
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. >
  11. <TextView
  12. android:id="@+id/tv"
  13. android:layout_width="fill_parent"
  14. android:layout_height="50dip"
  15. android:textColor="#FCFCFC"
  16. android:textSize="11pt"
  17. android:gravity="center_vertical"
  18. android:layout_marginLeft="10dip"
  19. />
  20. <ListView
  21. android:id="@+id/lv"
  22. android:layout_width="fill_parent"
  23. android:layout_height="381dip"
  24. android:cacheColorHint ="#00000000"
  25. ></ListView>
  26. </LinearLayout>
  27. <RelativeLayout
  28. android:layout_width="fill_parent"
  29. android:layout_height="53dip"
  30. android:orientation="horizontal"
  31. >
  32. <Button
  33. android:id="@+id/selectall"
  34. android:layout_width="80dip"
  35. android:layout_height="50dip"
  36. android:layout_marginLeft="20dip"
  37. android:text="全选"
  38. android:gravity="center"
  39. />
  40. <Button
  41. android:id="@+id/inverseselect"
  42. android:layout_width="80dip"
  43. android:layout_height="50dip"
  44. android:layout_marginLeft="118dip"
  45. android:text="反选"
  46. android:gravity="center"
  47. />
  48. <Button
  49. android:id="@+id/cancel"
  50. android:layout_width="80dip"
  51. android:layout_height="50dip"
  52. android:layout_marginLeft="213dip"
  53. android:text="取消已选"
  54. android:gravity="center"
  55. />
  56. </RelativeLayout>
  57. </LinearLayout>

ListView每个item的布局,listviewitem.xml:

这里需要注意的是,由于checkbox的点击事件优先级比listview的高,所以要添加android:focusable="false"属性,使得checkbox初始的时候没有获取焦点。

另外这里是点击ListView的item控制checkbox的状态改变,也就是让item接收clik事件,所以需要加上android:focusableInTouchMode="false"这一属性。

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="55dip"
  5. android:orientation="horizontal"
  6. android:layout_marginTop="20dip"
  7. >
  8. <TextView
  9. android:id="@+id/item_tv"
  10. android:layout_width="267dip"
  11. android:layout_height="40dip"
  12. android:textSize="10pt"
  13. android:gravity="center_vertical"
  14. android:layout_marginLeft="10dip"
  15. />
  16. <CheckBox
  17. android:id="@+id/item_cb"
  18. android:layout_width="wrap_content"
  19. android:layout_height="wrap_content"
  20. android:focusable="false"
  21. android:focusableInTouchMode="false"
  22. android:clickable="false"
  23. android:layout_toRightOf="@id/item_tv"
  24. android:layout_alignParentTop="true"
  25. android:layout_marginRight="5dip"
  26. />
  27. </RelativeLayout >

ViewHolder类

  1. package simtice.test.listview.viewholder;
  2. import android.widget.CheckBox;
  3. import android.widget.TextView;
  4. public class ViewHolder {
  5. public TextView tv = null;
  6. public CheckBox cb = null;
  7. }

为listview自定义适配器,该类为主Activity类MainActivity.java的内部类

  1. public static class MyAdapter extends BaseAdapter {
  2. public static HashMap<Integer, Boolean> isSelected;
  3. private Context context = null;
  4. private LayoutInflater inflater = null;
  5. private List<HashMap<String, Object>> list = null;
  6. private String keyString[] = null;
  7. private String itemString = null; // 记录每个item中textview的值
  8. private int idValue[] = null;// id值
  9. public MyAdapter(Context context, List<HashMap<String, Object>> list,
  10. int resource, String[] from, int[] to) {
  11. this.context = context;
  12. this.list = list;
  13. keyString = new String[from.length];
  14. idValue = new int[to.length];
  15. System.arraycopy(from, 0, keyString, 0, from.length);
  16. System.arraycopy(to, 0, idValue, 0, to.length);
  17. inflater = LayoutInflater.from(context);
  18. init();
  19. }
  20. // 初始化 设置所有checkbox都为未选择
  21. public void init() {
  22. isSelected = new HashMap<Integer, Boolean>();
  23. for (int i = 0; i < list.size(); i++) {
  24. isSelected.put(i, false);
  25. }
  26. }
  27. @Override
  28. public int getCount() {
  29. return list.size();
  30. }
  31. @Override
  32. public Object getItem(int arg0) {
  33. return list.get(arg0);
  34. }
  35. @Override
  36. public long getItemId(int arg0) {
  37. return 0;
  38. }
  39. @Override
  40. public View getView(int position, View view, ViewGroup arg2) {
  41. ViewHolder holder = null;
  42. if (holder == null) {
  43. holder = new ViewHolder();
  44. if (view == null) {
  45. view = inflater.inflate(R.layout.listviewitem, null);
  46. }
  47. holder.tv = (TextView) view.findViewById(R.id.item_tv);
  48. holder.cb = (CheckBox) view.findViewById(R.id.item_cb);
  49. view.setTag(holder);
  50. } else {
  51. holder = (ViewHolder) view.getTag();
  52. }
  53. HashMap<String, Object> map = list.get(position);
  54. if (map != null) {
  55. itemString = (String) map.get(keyString[0]);
  56. holder.tv.setText(itemString);
  57. }
  58. holder.cb.setChecked(isSelected.get(position));
  59. return view;
  60. }
  61. }

最后,最重要的就是MainActivity.java中一些事件响应的处理

  1. public class MainActivity extends Activity {
  2. TextView tv = null;
  3. ListView lv = null;
  4. Button btn_selectAll = null;
  5. Button btn_inverseSelect = null;
  6. Button btn_calcel = null;
  7. String name[] = { "G1", "G2", "G3", "G4", "G5", "G6", "G7", "G8", "G9",
  8. "G10", "G11", "G12", "G13", "G14" };
  9. ArrayList<String> listStr = null;
  10. private List<HashMap<String, Object>> list = null;
  11. private MyAdapter adapter;
  12. @Override
  13. public void onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.main);
  16. tv = (TextView) this.findViewById(R.id.tv);
  17. lv = (ListView) this.findViewById(R.id.lv);
  18. btn_selectAll = (Button) this.findViewById(R.id.selectall);
  19. btn_inverseSelect = (Button) this.findViewById(R.id.inverseselect);
  20. btn_calcel = (Button) this.findViewById(R.id.cancel);
  21. showCheckBoxListView();
  22. //全选
  23. btn_selectAll.setOnClickListener(new OnClickListener(){
  24. @Override
  25. public void onClick(View arg0) {
  26. listStr = new ArrayList<String>();
  27. for(int i=0;i<list.size();i++){
  28. MyAdapter.isSelected.put(i,true);
  29. listStr.add(name[i]);
  30. }
  31. adapter.notifyDataSetChanged();//注意这一句必须加上,否则checkbox无法正常更新状态
  32. tv.setText("已选中"+listStr.size()+"项");
  33. }
  34. });
  35. //反选
  36. btn_inverseSelect.setOnClickListener(new OnClickListener(){
  37. @Override
  38. public void onClick(View v) {
  39. for(int i=0;i<list.size();i++){
  40. if(MyAdapter.isSelected.get(i)==false){
  41. MyAdapter.isSelected.put(i, true);
  42. listStr.add(name[i]);
  43. }
  44. else{
  45. MyAdapter.isSelected.put(i, false);
  46. listStr.remove(name[i]);
  47. }
  48. }
  49. adapter.notifyDataSetChanged();
  50. tv.setText("已选中"+listStr.size()+"项");
  51. }
  52. });
  53. //取消已选
  54. btn_calcel.setOnClickListener(new OnClickListener(){
  55. @Override
  56. public void onClick(View v) {
  57. for(int i=0;i<list.size();i++){
  58. if(MyAdapter.isSelected.get(i)==true){
  59. MyAdapter.isSelected.put(i, false);
  60. listStr.remove(name[i]);
  61. }
  62. }
  63. adapter.notifyDataSetChanged();
  64. tv.setText("已选中"+listStr.size()+"项");
  65. }
  66. });
  67. }
  68. // 显示带有checkbox的listview
  69. public void showCheckBoxListView() {
  70. list = new ArrayList<HashMap<String, Object>>();
  71. for (int i = 0; i < name.length; i++) {
  72. HashMap<String, Object> map = new HashMap<String, Object>();
  73. map.put("item_tv", name[i]);
  74. map.put("item_cb", false);
  75. list.add(map);
  76. adapter = new MyAdapter(this, list, R.layout.listviewitem,
  77. new String[] { "item_tv", "item_cb" }, new int[] {
  78. R.id.item_tv, R.id.item_cb });
  79. lv.setAdapter(adapter);
  80. listStr = new ArrayList<String>();
  81. lv.setOnItemClickListener(new OnItemClickListener() {
  82. @Override
  83. public void onItemClick(AdapterView<?> arg0, View view,
  84. int position, long arg3) {
  85. ViewHolder holder = (ViewHolder) view.getTag();
  86. holder.cb.toggle();// 在每次获取点击的item时改变checkbox的状态
  87. MyAdapter.isSelected.put(position, holder.cb.isChecked()); // 同时修改map的值保存状态
  88. if (holder.cb.isChecked() == true) {
  89. listStr.add(name[position]);
  90. } else {
  91. listStr.remove(name[position]);
  92. }
  93. tv.setText("已选中"+listStr.size()+"项");
  94. }
  95. });
  96. }
  97. }
  98. //为listview自定义适配器内部类
  99. public static class MyAdapter extends BaseAdapter {
  100. ...
  101. }
  102. }

好了,来看运行结果

我选择了G2、G3、G11三项,现在屏幕滑动到底部,看以看到状态保存的很好,TextView显示已选中3项。全选、反选、取消全选功能正常,多选操作完美解决!

Android在listview添加checkbox实现单选多选操作问题(转)的更多相关文章

  1. Android在listview添加checkbox实现单选多选操作问题

    android根据View的不同状态更换不同的背景http://www.eoeandroid.com/thread-198029-1-1.html android 模仿朋友网推出的菜单效果[改进版]h ...

  2. 完美解决Android在listview添加checkbox实现单选多选操作问题

    在Android某些开发需求当中,有时候需要在listveiw中加入checkbox实现单选,多选操作.表面上看上去只是改变checkbox那么简单,然而实际开发中,实现起来并不是那么得心应手.尤其当 ...

  3. Android之listview添加数据篇

    一.ListView: 1. ListView通常有两个职责: 1.向布局填充数据 2.处理选择点击等操作 2.ListView的创建需要3个元素: 1. ListView中的每一列的View. 2. ...

  4. Android中ListView结合CheckBox判断选中项

    本文主要实现在自定义的ListView布局中加入CheckBox控件,通过判断用户是否选中CheckBox来对ListView的选中项进行相应的操作.通过一个Demo来展示该功能,选中ListView ...

  5. JsTree中节点添加CheckBox 以及 单选的实现

    stree中添加checkbox,需要在初始化时设置plugins属性: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 $('#DpTree').data('jstree', fa ...

  6. ListView加checkBox可以实现全选等功能

    1.效果图 2.LIteView_item布局 <?xml version="1.0" encoding="utf-8"?> <Relativ ...

  7. checkbox的单选全选,反选,计算价格,删除

    activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...

  8. Android ListView带CheckBox实现单选

    第1种方法: 首先是我们的bean: public class Bean { private boolean isChecked; private String msg = "这是一条测试数 ...

  9. Android 的 ListView 的CheckBox标题栏显示文本之后显示单选框

    https://blog.csdn.net/u013790519/article/details/50036223 2.CheckBox的android:button=”@null”属性代码设置如下: ...

随机推荐

  1. 《oracle每日一练》免安装Oracle客户端使用PL/SQL

    免安装Oracle客户端使用PL/SQL Oracle客户端挺招人烦的,部署连接它的应用通常需要先安装它的客户端,安装程序要求在目标机器上写注册表,假设你没有洁癖的话,你仍可能被下面的事情绊住:当你的 ...

  2. 使用Java的多线程和IO流写一个文件复制功能类

    创建一个复制功能类,继承Thread类,重写run()方法,把FileInputStream和FileOutputStream输入输出流写在run()方法内.示例代码如下: import java.i ...

  3. Mac下安装MySQL

    2015-07-13 15:10:32 Mac下用homebrew安装软件还是很方便的 brew install mysql 等待一会儿安装完毕后到安装目录: /usr/local/Cellar/my ...

  4. 2.nodejs权威指南--Buffer

    1. Buffer 1.1 创建 var buf1 = new Buffer(100); var buf2 = new Buffer([0,1,2]); var buf3 = new Buffer(' ...

  5. Match:DNA repair(POJ 3691)

    基因修复 题目大意:给定一些坏串,再给你一个字符串,要你修复这个字符串(AGTC随便换),使之不含任何坏串,求修复所需要的最小步数. 这一题也是和之前的那个1625的思想是一样的,通过特殊的trie树 ...

  6. C Primer Plus_第二章_C语言概述_复习题与编程练习

    REVIEW 1.如何称呼C程序的基本模块? ans 它们被称为函数 2.什么是语法错误?给出一个英语例子和一个C语言例子 me C的语法错误是指把正确的C符号放在了错误的位置 likes codin ...

  7. 轻轻送送为你的App加点特效

    前言 今天突然在一个应用中看到一个转场动画,蛮有意思的 退出动画 进入动画 ActivityOptionsCompat options = ActivityOptionsCompat.makeScal ...

  8. SQL Server output经典使用

    output经典使用 分类: sql2012-02-16 18:17 409人阅读 评论(0) 收藏 举报 outputinserttabledeletegonull OUTPUT是SQL SERVE ...

  9. August 24th 2016 Week 35th Wednesday

    Storms make trees take deeper roots. 暴风雨能使大树的根扎得更深. If the trees already have deep roots, then the s ...

  10. Python--常见问题解决方案

    1.如何支持中文,在第一行加上编码格式的支持: # coding=gbk +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...