ListView加CheckBox简单实现批量删除

前段时间要做一个批量删除的功能,身为初学者的我,开始尝试做这个功能,但是出现了以下3个情况:

  1. checkbox被勾选上后,listview滑走再滑回来,本来应该被选中的checkbox成了未选中状态
  2. 连续勾选后,删除的不完整,比如我同时勾上了第3、4、5个item,点击删除后第3、5个倒是被删除了,第4个没有被删除
  3. 乱序,明明选择的是第2个,点击删除的时候,随机的一个被删除了

本来在网上查了一些解决的方法,但是都太复杂了(个人感觉),一个简单的批量删除,居然用map这么高级的东西,所以我分享一下我解决的方法。
先上效果图:
批量删除效果图
界面超级简单,完全是为了做批量删除而的一个小例子,也没有夹杂一些别的东西,比如全选反选之类的,我喜欢一篇文章只说一个问题,

使用到的类

  1. MainActivity:不解释
  2. MyAdapter:listview的适配器
  3. Entity:实体类,封装了listview的item的内容

接下来一个一个解释,每个类到底有什么东西
先说最简的Entity
代表着每一个item的内容

//是否被选中
private boolean isSelect;
//文本内容
private String text;

就两个属性,别的都是一些get、set方法,tostring什么的。

接下来是MyAdapter类:
继承BaseAdapter,实现对应的4个方法
以下是继承BaseAdapter的常见手段(方法)

    private ArrayList<Entity> datas = new ArrayList<>();
    private LayoutInflater inflater;

    public MyAdapter(Context context) {
        inflater = LayoutInflater.from(context);
    }

    public void setList(ArrayList<Entity> list) {
        this.datas = list;
    }

现在说说最重要的getView方法

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //使用viewholder优化listview
        ViewHolder holder;

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.item, null);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        //将position传递给checkbox监听的实现类
        //说白了就是让chechbox知道它在listview的哪个位置
        //好处就是,删除的时候不会乱了,不会因为选中的是a而把b删了(解决乱序)
        //因为checkbox知道自己的位置了嘛
        holder.checkbox.setTag(position);
        holder.text.setText(datas.get(position).getText());

        //给checkbox设置监听
        //使他被选中的时候做一些事情
        //比如将对应的entity的isSelect改为true
        holder.checkbox.setOnCheckedChangeListener(listener);

        //给checkbox设置状态,是否被选中
        //通过获取对应的entity,取得里面的isSelect的值修改
        //解决选中后,listview滑动走再滑回来,checkbox又没有选的尴尬
        holder.checkbox.setChecked(datas.get(position).isSelect());

        return convertView;
    }

    private CompoundButton.OnCheckedChangeListener listener = new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            //获取传递来的position,点击listview列表中的checkbox的时候,就能知道是点击的哪个了
            int pos = (int) buttonView.getTag();
            //将集合中对应的entity中对应的isSelect设置为checkbox的状态(是否被选中true/false)
            getItem(pos).setSelect(isChecked);
        }
    };

    public static class ViewHolder {
        public View rootView;
        public TextView text;
        public CheckBox checkbox;

        public ViewHolder(View rootView) {
            this.rootView = rootView;
            this.text = (TextView) rootView.findViewById(R.id.text);
            this.checkbox = (CheckBox) rootView.findViewById(R.id.checkbox);
        }

    }

准备工作都做完了,我们来看看MainActivity中的具体实现
布局很简单,线性布局,方向垂直,上面一个批量删除的按钮,下面是listview。
先来感受一下MainActivity里面的内容:

public class MainActivity extends AppCompatActivity  {

    private ListView listview;
    private Button del;
    private MyAdapter adapter;

    private ArrayList<Entity> datas;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        datas = new ArrayList<>();

        for (int i = 0; i < 30; i++) {
            datas.add(new Entity(false, "item" + i));
        }

        listview = (ListView) findViewById(R.id.listview);
        del = (Button) findViewById(R.id.del);

        adapter = new MyAdapter(this);
        adapter.addData(datas);
        listview.setAdapter(adapter);

        del.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                ArrayList<Entity> data = adapter.getData();

                for (int i = 0; i < data.size(); i++) {
                    if (data.get(i).isSelect()) {
                        data.remove(i);
                        i--;
                    }
                }
                adapter.setList(data);
                adapter.notifyDataSetChanged();

            }
        });

    }

}

别的都没上什么说的,我们来看看点击事件里面有个i - -,这是干嘛的呢,为什么要这么写呢,不写会有什么后果呢?
不写的后果很严重,就是连续勾选item后,点击删除,不会全部被删除,为什么会这样,这要牵扯到ArrayList的结构。大家都知道ArrayList是类似数组的结构,所以,
来看一张我用画图工具画的渣图
ArrayList
该图表示arraylist中有很多数据,其中梨子的位置是1,香蕉的位置是2,当我们删除了梨子后,本来应该第2的香蕉,变成的位置1,也就是梨子后面所有的数据都想前挪动了一位(感觉好耗资源啊)

所以当我们连续选择又没有i- -时候,画图最清楚,上图!
这里写图片描述
这里解释下:

图1:当我们选中234的时候,实际上是将每一个item对应的entity中的isSelect值改为了true。

图2:点击删除后,系统开始循环遍历整个集合,为true就删除,该循环只执行一次,
所以当循环到了位置2的时候,发现是true,不解释直接删除,此时集合中的数据位置为图2,
位置2已被item3代替

图3:继续循环,到了位置3,发现是item4,一看值为true,直接删,此时集合中的数据位置为图3

所以最终结果就是item3瞒天过海了。。。

结论

在for循环中,我们指定了循环的次数,int times = date.size(),但是当我们删除了集合中的一个数据后,times已经发生改变了,为了不使他改变,删除一个就i- -一次,这样,就能保证循环的次数和集合尺寸一样了,就能完美实现批量删除了。

源码

http://download.csdn.net/detail/it_xf/9569331

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值