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解决复用问题。
????? ? 效果图如下:
首先,我们先看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实现真正的多选、全选、反选、取消。
上一篇: 实例分析:光纤断裂应急处理方案