Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能

来源:互联网 发布:2018网络教育报名时间 编辑:程序博客网 时间:2024/05/17 07:32

标签: androidlistview控件checkbox图片

 分类:

目录(?)[+]

Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能


这个控件还是挺复杂的,也是项目中应该算是比较常用的了,所以写了一个小Demo来讲讲,主要是自定义adapter的用法,加了很多的判断等等等等….我们先来看看实现的效果吧!

这里写图片描述

好的,我们新建一个项目LvCheckBox

这里写图片描述

我们事先先把这两个布局写好吧,一个是主布局,还有一个listview的item.xml,相信不用多说

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="50dp"        android:background="#238286" >        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerInParent="true"            android:text="ListView绑定CheckBox"            android:textColor="#fff" />        <TextView            android:id="@+id/tv_add"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_centerVertical="true"            android:layout_marginRight="17dp"            android:text="增加"            android:textColor="#fff" />    </RelativeLayout>    <ListView        android:id="@+id/listview"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1" >    </ListView>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp"        android:orientation="horizontal" >        <Button            android:id="@+id/btn_detele"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:layout_marginRight="1dp"            android:layout_weight="1"            android:background="#238286"            android:text="删除"            android:textColor="#fff" />        <Button            android:id="@+id/btn_select_all"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:layout_marginLeft="1dp"            android:layout_weight="1"            android:background="#238286"            android:text="全选"            android:textColor="#fff" />    </LinearLayout></LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

item.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="50dp"    android:gravity="center_vertical"    android:orientation="horizontal" >    <TextView        android:id="@+id/tvTitle"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="15dp"        android:layout_weight="7"        android:text="text" />    <CheckBox        android:id="@+id/cbCheckBox"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_weight="1" /></LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

item.xml只有两个控件,很好理解吧

初始化控件

我们用initView()方法来初始化这些控件
    private void initView() {        tv_add = (TextView) findViewById(R.id.tv_add);        tv_add.setOnClickListener(this);        btn_detele = (Button) findViewById(R.id.btn_detele);        btn_detele.setOnClickListener(this);        btn_select_all = (Button) findViewById(R.id.btn_select_all);        btn_select_all.setOnClickListener(this);        listview = (ListView) findViewById(R.id.listview);    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

然后继承点击事件,button的和listview的

implements OnClickListener,OnItemClickListener
  • 1
  • 1

自定义Adapter

这里最难的就是adapter了

1.Bean

我们为了数据的记录方便,我们提前写一个实体类
package com.lgl.lvcheckbox;public class Bean {    private String title;    // 构造方法    public Bean(String title) {        super();        this.title = title;    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

ListAdapter

这里所有的都写了注释,也方便大家看清
package com.lgl.lvcheckbox;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;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.CompoundButton;import android.widget.CompoundButton.OnCheckedChangeListener;import android.widget.TextView;/** * 自定义适配器 *  * @author LGL * */public class ListAdapter extends BaseAdapter {    // 数据集    private List<Bean> list = new ArrayList<Bean>();    // 上下文    private Context mContext;    // 存储勾选框状态的map集合    private Map<Integer, Boolean> isCheck = new HashMap<Integer, Boolean>();    // 构造方法    public ListAdapter(Context mContext) {        super();        this.mContext = mContext;        // 默认为不选中        initCheck(false);    }    // 初始化map集合    public void initCheck(boolean flag) {        // map集合的数量和list的数量是一致的        for (int i = 0; i < list.size(); i++) {            // 设置默认的显示            isCheck.put(i, flag);        }    }    // 设置数据    public void setData(List<Bean> data) {        this.list = data;    }    // 添加数据    public void addData(Bean bean) {        // 下标 数据        list.add(0, bean);    }    @Override    public int getCount() {        // TODO Auto-generated method stub        // 如果为null就返回一个0        return list != null ? list.size() : 0;    }    @Override    public Object getItem(int position) {        // TODO Auto-generated method stub        return list.get(position);    }    @Override    public long getItemId(int position) {        // TODO Auto-generated method stub        return position;    }    @Override    public View getView(final int position, View convertView, ViewGroup parent) {        ViewHolder viewHolder = null;        View view = null;        // 判断是不是第一次进来        if (convertView == null) {            view = LayoutInflater.from(mContext).inflate(R.layout.item, null);            viewHolder = new ViewHolder();            viewHolder.title = (TextView) view.findViewById(R.id.tvTitle);            viewHolder.cbCheckBox = (CheckBox) view                    .findViewById(R.id.cbCheckBox);            // 标记,可以复用            view.setTag(viewHolder);        } else {            view = convertView;            // 直接拿过来用            viewHolder = (ViewHolder) view.getTag();        }        // 拿到对象        Bean bean = list.get(position);        // 填充数据        viewHolder.title.setText(bean.getTitle().toString());        // 勾选框的点击事件        viewHolder.cbCheckBox                .setOnCheckedChangeListener(new OnCheckedChangeListener() {                    @Override                    public void onCheckedChanged(CompoundButton buttonView,                            boolean isChecked) {                        // 用map集合保存                        isCheck.put(position, isChecked);                    }                });        // 设置状态        if (isCheck.get(position) == null) {            isCheck.put(position, false);        }        viewHolder.cbCheckBox.setChecked(isCheck.get(position));        return view;    }    // 优化    public static class ViewHolder {        public TextView title;        public CheckBox cbCheckBox;    }    // 全选按钮获取状态    public Map<Integer, Boolean> getMap() {        // 返回状态        return isCheck;    }    // 删除一个数据    public void removeData(int position) {        list.remove(position);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138

当然,有些方法是后面写的,我们提前写好,比如删除和增加什么的

初始化数据

我们默认总是需要点数据的
    private void initData() {        // 默认显示的数据        List<Bean> list = new ArrayList<Bean>();        list.add(new Bean("张三"));        list.add(new Bean("李四"));        list.add(new Bean("王五"));        adapter = new ListAdapter(this);        adapter.setData(list);        listview.setAdapter(adapter);    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

增加数据

    // 添加数据        case R.id.tv_add:            adapter.addData(new Bean("刘桂林"));            // 通知刷新适配器            adapter.notifyDataSetChanged();            break;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

全选数据

当我们全选的时候,按钮应该为全不选的,所以这里我们这里有状态的
    case R.id.btn_select_all:            // 全选——全不选            Map<Integer, Boolean> isCheck = adapter.getMap();            if (btn_select_all.getText().equals("全选")) {                adapter.initCheck(true);                // 通知刷新适配器                adapter.notifyDataSetChanged();                btn_select_all.setText("全不选");                btn_select_all.setTextColor(Color.YELLOW);            } else if (btn_select_all.getText().equals("全不选")) {                adapter.initCheck(false);                // 通知刷新适配器                adapter.notifyDataSetChanged();                btn_select_all.setText("全选");                btn_select_all.setTextColor(Color.YELLOW);            }            break;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

删除数据

删除也是要考虑很多因素
// 删除数据        case R.id.btn_detele:            // 拿到所有数据            Map<Integer, Boolean> isCheck_delete = adapter.getMap();            // 获取到条目数量,map.size = list.size,所以            int count = adapter.getCount();            // 遍历            for (int i = 0; i < count; i++) {                // 删除有两个map和list都要删除 ,计算方式                int position = i - (count - adapter.getCount());                // 判断状态 true为删除                if (isCheck_delete.get(i) != null && isCheck_delete.get(i)) {                    // listview删除数据                    isCheck_delete.remove(i);                    adapter.removeData(position);                }            }            btn_select_all.setText("全选");            btn_select_all.setTextColor(Color.WHITE);            adapter.notifyDataSetChanged();            break;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

这里的

int position = i - (count - adapter.getCount());
  • 1
  • 1

是一个计算方式,当我们删除之后,实际上数组是需要重新排列的,同时按钮也要变回全选状态的

这里写图片描述

listview的点击

我们直接点击也是可以勾选cheakbox选中的
// listview的点击事件    @Override    public void onItemClick(AdapterView<?> parent, View view, int position,            long id) {        // 判断view是否相同        if (view.getTag() instanceof ViewHolder) {            // 如果是的话,重用            ViewHolder holder = (ViewHolder) view.getTag();            // 自动触发            holder.cbCheckBox.toggle();        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

好的,这样的话就可以实现了,如果不懂的话可以下载本文demo参考,觉得好的点个赞

Demo下载地址:http://download.csdn.net/detail/qq_26787115/9423306

0 0