Android 带checkbox的listView 实现多选,全选,反选

时间:2021-11-02 06:41:36
由于listview的一些特性,刚开始写这种需求的功能的时候都会碰到一些问题,重点就是存储每个checkbox的状态值,在这里分享出了完美解决方法:
 
Android 带checkbox的listView 实现多选,全选,反选
 
布局文件:
[html]  
<?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:orientation="horizontal" >  
  
    <TextView  
        android:id="@+id/tv"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:layout_gravity="center_vertical" />  
  
    <LinearLayout  
        android:id="@+id/line"  
        android:layout_width="fill_parent"  
        android:layout_height="50dp"  
        android:layout_below="@+id/tv"  
        android:orientation="horizontal" >  
  
        <Button  
            android:id="@+id/bt_selectall"  
            android:layout_width="80dp"  
            android:layout_height="fill_parent"  
            android:text="全选" />  
  
             <Button  
            android:id="@+id/bt_cancleselectall"  
            android:layout_width="80dp"  
            android:layout_height="fill_parent"  
            android:text="反选" />  
               
          
        <Button  
            android:id="@+id/bt_deselectall"  
            android:layout_width="80dp"  
            android:layout_height="fill_parent"  
            android:text="取消选择" />  
  
    </LinearLayout>  
  
    <ListView  
        android:id="@+id/lv"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        android:layout_below="@+id/line" />  
  
</RelativeLayout>  
 
 
 
listView 的item布局文件:
 
[html] 
<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:orientation="horizontal" >  
  
    <TextView  
        android:id="@+id/item_tv"  
        android:layout_width="0dp"  
        android:layout_height="wrap_content"  
        android:layout_gravity="center_vertical"  
        android:layout_weight="1" />  
  
    <CheckBox  
        android:id="@+id/item_cb"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:clickable="false"  
        android:focusable="false"  
        android:focusableInTouchMode="false"  
        android:gravity="center_vertical" />  
  
</LinearLayout>  
 
 
Activity:
 
[java]  
public class Ex_checkboxActivity extends Activity {  
    private ListView lv;  
    private MyAdapter mAdapter;  
    private ArrayList<String> list;  
    private Button bt_selectall;  
    private Button bt_cancel;  
    private Button bt_deselectall;  
    private int checkNum; // 记录选中的条目数量  
    private TextView tv_show;// 用于显示选中的条目数量  
  
    /** Called when the activity is first created. */  
  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        /* 实例化各个控件 */  
        lv = (ListView) findViewById(R.id.lv);  
        bt_selectall = (Button) findViewById(R.id.bt_selectall);  
        bt_cancel = (Button) findViewById(R.id.bt_cancelselectall);  
        bt_deselectall = (Button) findViewById(R.id.bt_deselectall);  
        tv_show = (TextView) findViewById(R.id.tv);  
        list = new ArrayList<String>();  
        // 为Adapter准备数据  
        initDate();  
        // 实例化自定义的MyAdapter  
        mAdapter = new MyAdapter(list, this);  
        // 绑定Adapter  
        lv.setAdapter(mAdapter);  
  
        // 全选按钮的回调接口  
        bt_selectall.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                // 遍历list的长度,将MyAdapter中的map值全部设为true  
                for (int i = 0; i < list.size(); i++) {  
                    MyAdapter.getIsSelected().put(i, true);  
                }  
                // 数量设为list的长度  
                checkNum = list.size();  
                // 刷新listview和TextView的显示  
                dataChanged();  
            }  
        });  
  
        // 反选按钮的回调接口  
        bt_cancel.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                // 遍历list的长度,将已选的设为未选,未选的设为已选  
                for (int i = 0; i < list.size(); i++) {  
                    if (MyAdapter.getIsSelected().get(i)) {  
                        MyAdapter.getIsSelected().put(i, false);  
                        checkNum--;  
                    } else {  
                        MyAdapter.getIsSelected().put(i, true);  
                        checkNum++;  
                    }  
                }  
                // 刷新listview和TextView的显示  
                dataChanged();  
            }  
        });  
  
        // 取消按钮的回调接口  
        bt_deselectall.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                // 遍历list的长度,将已选的按钮设为未选  
                for (int i = 0; i < list.size(); i++) {  
                    if (MyAdapter.getIsSelected().get(i)) {  
                        MyAdapter.getIsSelected().put(i, false);  
                        checkNum--;// 数量减1  
                    }  
                }  
                // 刷新listview和TextView的显示  
                dataChanged();  
            }  
        });  
  
        // 绑定listView的监听器  
        lv.setOnItemClickListener(new OnItemClickListener() {  
            @Override  
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,  
                    long arg3) {  
                // 取得ViewHolder对象,这样就省去了通过层层的findViewById去实例化我们需要的cb实例的步骤  
                ViewHolder holder = (ViewHolder) arg1.getTag();  
                // 改变CheckBox的状态  
                holder.cb.toggle();  
                // 将CheckBox的选中状况记录下来  
                MyAdapter.getIsSelected().put(arg2, holder.cb.isChecked());  
                // 调整选定条目  
                if (holder.cb.isChecked() == true) {  
                    checkNum++;  
                } else {  
                    checkNum--;  
                }  
                // 用TextView显示  
                tv_show.setText("已选中" + checkNum + "项");  
            }  
        });  
    }  
  
    // 初始化数据  
    private void initDate() {  
        for (int i = 0; i < 15; i++) {  
            list.add("data" + " " + i);  
        }  
        ;  
    }  
    // 刷新listview和TextView的显示  
    private void dataChanged() {  
        // 通知listView刷新  
        mAdapter.notifyDataSetChanged();  
        // TextView显示最新的选中数目  
        tv_show.setText("已选中" + checkNum + "项");  
    };  
}  
 
 
列表适配器:
 
[java]  
package com.notice.listcheck;  
  
import java.util.ArrayList;  
import java.util.HashMap;  
  
import android.content.Context;  
import android.view.LayoutInflater;  
import android.view.View;  
import android.view.ViewGroup;  
import android.widget.BaseAdapter;  
import android.widget.CheckBox;  
import android.widget.TextView;  
  
public class MyAdapter extends BaseAdapter {  
    // 填充数据的list  
    private ArrayList<String> list;  
    // 用来控制CheckBox的选中状况  
    private static HashMap<Integer, Boolean> isSelected;  
    // 上下文  
    private Context context;  
    // 用来导入布局  
    private LayoutInflater inflater = null;  
  
    // 构造器  
    public MyAdapter(ArrayList<String> list, Context context) {  
        this.context = context;  
        this.list = list;  
        inflater = LayoutInflater.from(context);  
        isSelected = new HashMap<Integer, Boolean>();  
        // 初始化数据  
        initDate();  
    }  
  
    // 初始化isSelected的数据  
    private void initDate() {  
        for (int i = 0; i < list.size(); i++) {  
            getIsSelected().put(i, false);  
        }  
    }  
  
    @Override  
    public int getCount() {  
        return list.size();  
    }  
  
    @Override  
    public Object getItem(int position) {  
        return list.get(position);  
    }  
  
    @Override  
    public long getItemId(int position) {  
        return position;  
    }  
  
    @Override  
    public View getView(int position, View convertView, ViewGroup parent) {  
        ViewHolder holder = null;  
        if (convertView == null) {  
            // 获得ViewHolder对象  
            holder = new ViewHolder();  
            // 导入布局并赋值给convertview  
            convertView = inflater.inflate(R.layout.listviewitem, null);  
            holder.tv = (TextView) convertView.findViewById(R.id.item_tv);  
            holder.cb = (CheckBox) convertView.findViewById(R.id.item_cb);  
            // 为view设置标签  
            convertView.setTag(holder);  
        } else {  
            // 取出holder  
            holder = (ViewHolder) convertView.getTag();  
        }  
        // 设置list中TextView的显示  
        holder.tv.setText(list.get(position));  
        // 根据isSelected来设置checkbox的选中状况  
        holder.cb.setChecked(getIsSelected().get(position));  
        return convertView;  
    }  
  
    public static HashMap<Integer, Boolean> getIsSelected() {  
        return isSelected;  
    }  
  
    public static void setIsSelected(HashMap<Integer, Boolean> isSelected) {  
        MyAdapter.isSelected = isSelected;  
    }  
  
    public static class ViewHolder {  
        TextView tv;  
        CheckBox cb;  
    }