欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android 实现ListView嵌套Checkbox实现真正的多选、全选、反选、取消

程序员文章站 2022-04-14 09:37:54
android 实现listview嵌套checkbox实现真正的多选、全选、反选、取消 我们在开发app的时候,很多情况下会使用到listview嵌套checkbox的情况,例如购物车选择商品的情...

android 实现listview嵌套checkbox实现真正的多选、全选、反选、取消

我们在开发app的时候,很多情况下会使用到listview嵌套checkbox的情况,例如购物车选择商品的情况,其实很多人要说这个其实很简单了,并没有那么复杂,事实上并非如此,我们在使用listview嵌套checkbox复选框的时候会出现很多问题,接下来我将用一篇博客来说明这些问题,给大家一些参照,解决listview嵌套checkbox解决复用问题。

????? ? 效果图如下:

android 实现ListView嵌套Checkbox实现真正的多选、全选、反选、取消

首先,我们先看mainactivity中的布局,




    
    
接下来看mainactivity的代码如下:
package com.example.cx.listviewdemo;

import android.os.bundle;
import android.support.v7.app.appcompatactivity;
import android.view.view;
import android.widget.adapterview;
import android.widget.button;
import android.widget.listview;
import android.widget.toast;
import java.util.arraylist;
import java.util.list;

public class mainactivity extends appcompatactivity implements view.onclicklistener {

    private listview mlv;
    private button mbtnselectall, mbtnunselectall, mbtndelete, mbtncancel;
    //数据源
    private list mdatalist;

    //与条目对应的选中状态
    private list mcheckedlist;
    private myadapter madapter;
    
    
    @override
    protected void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        setcontentview(r.layout.activity_main);
        initview();
        mdatalist = new arraylist();
        mcheckedlist = new arraylist();

        for (int i = 0; i < 50; i++) {
            mdatalist.add("数据" + i);
            mcheckedlist.add(false);
        }
        madapter = new myadapter(mainactivity.this, mdatalist);
        madapter.setdata(mdatalist, mcheckedlist);
        mlv.setadapter(madapter);


        mlv.setonitemclicklistener(new adapterview.onitemclicklistener() {
            @override
            public void onitemclick(adapterview parent, view view, int position, long id) {
                toast.maketext(mainactivity.this, "条目" + position + "被点击了", toast.length_short).show();

                mcheckedlist.set(position, !mcheckedlist.get(position));
                madapter.setdata(mdatalist, mcheckedlist);
                madapter.notifydatasetchanged();

            }
        });
    }

    private void initview() {
        mlv = (listview) findviewbyid(r.id.lv);
        mbtnselectall = findviewbyid(r.id.btn_all_select);
        mbtnunselectall = findviewbyid(r.id.btn_all_unselect);
        mbtndelete = findviewbyid(r.id.btn_delete);
        mbtncancel = findviewbyid(r.id.btn_cancel);

        mbtnselectall.setonclicklistener(this);
        mbtnunselectall.setonclicklistener(this);
        mbtndelete.setonclicklistener(this);
        mbtncancel.setonclicklistener(this);
    }
    
    @override
    public void onclick(view v) {
        switch (v.getid()) {
            //全选
            case r.id.btn_all_select:
                select_all();
                break;

            //反选
            case r.id.btn_all_unselect:
                unselect_all();
                break;
                
            //删除
            case r.id.btn_delete:
                delete();
                break;

            //取消
            case r.id.btn_cancel:
                cancel();
                break;
        }
    }

    // 全选
    private void select_all() {
        for (int i = 0; i < mcheckedlist.size(); i++) {
            mcheckedlist.set(i, true);
        }
        madapter.setdata(mdatalist, mcheckedlist);
        madapter.notifydatasetchanged();
    }


    //取消
    private void cancel() {
        for (int i = 0; i < mcheckedlist.size(); i++) {
            mcheckedlist.set(i, false);
        }
        madapter.setdata(mdatalist, mcheckedlist);
        madapter.notifydatasetchanged();

    }

    //删除
    private void delete() {
        for (int i = 0; i < mcheckedlist.size(); i++) {
            if (mcheckedlist.get(i)) {
                mcheckedlist.remove(i);
                mdatalist.remove(i);
                i--;
            }
        }
        madapter.setdata(mdatalist, mcheckedlist);
        madapter.notifydatasetchanged();
    }

    //反选
    private void unselect_all() {
        for (int i = 0; i < mcheckedlist.size(); i++) {
            mcheckedlist.set(i, !mcheckedlist.get(i));
        }
        madapter.setdata(mdatalist, mcheckedlist);
        madapter.notifydatasetchanged();
    }
}

主要是adapter 的代码,里面解决了listview 嵌套checkbox的问题。比如,当选中item中的checkbox时然后上下滑动,这时你会发现item会被复用,什么意思呢?就是当你上下滑动listview时,选中的checkbox会被取消,这个问题跟listview加载图片时会错位一样,都是事件分发机制造成的,具体解决接下来看操作:

package com.example.cx.listviewdemo;

import android.content.context;
import android.content.sharedpreferences;
import android.view.view;
import android.view.viewgroup;
import android.widget.baseadapter;
import android.widget.checkbox;
import android.widget.compoundbutton;
import android.widget.textview;
import java.util.list;


public class myadapter extends baseadapter {
    private context mcontext;
    private list mdatalist;
    private list mcheckedlist;
    private sharedpreferences msp;

    public myadapter(context context, list mdatalist) {
        this.mcontext = context;
        this.mdatalist = mdatalist;
        msp = mcontext.getsharedpreferences("config", context.mode_private);
    }


    //会被多次调用(只要listview条目个数发生变化的时候)
    public void setdata(list datalist, list checkedlist) {
        this.mdatalist = datalist;
        this.mcheckedlist = checkedlist;
    }

    @override
    public int getcount() {
        return mdatalist.size();
    }

    @override
    public object getitem(int position) {
        return mdatalist.get(position);
    }

    @override
    public long getitemid(int position) {
        return position;
    }



    //图片错位: 给加载的图片设计tag(url)标记,复用之后再次滑动当前条目,判断当前图片url和这个tag标记是否一致,如果一致就显示,如果不一致就不显示

    @override
    public view getview(final int position, view convertview, viewgroup parent) {
        viewholder viewholder = null;
        if (viewholder == null) {
            viewholder = new viewholder();
            convertview = view.inflate(mcontext, r.layout.layout_list_item, null);
            viewholder.mtv = convertview.findviewbyid(r.id.item_tv);
            viewholder.mcb = convertview.findviewbyid(r.id.item_cb);
            convertview.settag(viewholder);

        } else {
            viewholder = (viewholder) convertview.gettag();
        }

        viewholder.mtv.settext(mdatalist.get(position));
        viewholder.mcb.setchecked(mcheckedlist.get(position));

        viewholder.mcb.setoncheckedchangelistener(new compoundbutton.oncheckedchangelistener() {
            @override
            public void oncheckedchanged(compoundbutton buttonview, boolean ischecked) {
                mcheckedlist.set(position, ischecked);
                notifydatasetchanged();
            }
        });

        return convertview;
    }


    public static class viewholder {
        textview mtv;
        checkbox mcb;
    }
}
这是适配器布局代码:


    
    
    
    

这样我们就实现了listview嵌套checkbox实现真正的多选、全选、反选、取消。