ExpandableListView实现二级列表购物车
程序员文章站
2023-11-14 14:26:04
android中常常要用到listview,有时也要用到expandablelistview,如在手机设置中,对于分类有很好的效果,会用listview的人一定会用expa...
android中常常要用到listview,有时也要用到expandablelistview,如在手机设置中,对于分类有很好的效果,会用listview的人一定会用expandablelistview,因为expandablelistview extends listview的,下面来看个简单的例子
运行效果图:
导入依赖
compile 'com.google.code.gson:gson:2.8.2' compile 'com.squareup.okhttp3:okhttp:3.9.0'
记得要把okhttp的原生文件夹复制进去,话不多说请看代码:
mainactivity布局:
<expandablelistview android:id="@+id/elv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> <relativelayout android:layout_width="match_parent" android:layout_height="40dp"> <checkbox android:id="@+id/cb" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centervertical="true" android:text="全选" /> <textview android:id="@+id/tvtotal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centervertical="true" android:layout_marginleft="15dp" android:layout_torightof="@id/cb" android:text="合计:" /> <textview android:id="@+id/tvcount" android:layout_width="100dp" android:layout_height="match_parent" android:layout_alignparentright="true" android:layout_centervertical="true" android:background="#ff0000" android:gravity="center" android:text="去结算(0)" android:textcolor="#ffffff" /> </relativelayout>
适配器的group布局:
<checkbox android:id="@+id/cb_group" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <textview android:id="@+id/tv_group" android:layout_width="match_parent" android:layout_height="40dp" android:gravity="center_vertical" android:text="111"/>
适配器child布局:
<checkbox android:id="@+id/cb_child" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <imageview android:id="@+id/iv" android:layout_width="100dp" android:layout_height="100dp" /> <linearlayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <textview android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <textview android:id="@+id/tv_subhead" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <textview android:id="@+id/tvsubhead" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal"> <textview android:id="@+id/tvprice" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <imageview android:layout_marginleft="10dp" android:id="@+id/ivdel" android:layout_width="25dp" android:layout_height="25dp" android:background="@drawable/iv_del" /> <textview android:id="@+id/tvnum" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textsize="25sp" android:layout_marginleft="3dp" android:layout_marginright="3dp" android:text="1"/> <imageview android:id="@+id/ivadd" android:layout_width="25dp" android:layout_height="25dp" android:background="@drawable/iv_add" /> </linearlayout> </linearlayout> <textview android:id="@+id/btdel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="删除" />
接下来看代码:
用mvp获取的数据首先先在项目里创建三个文件夹分别是:model、view、persenter
model页面代码传的参数:
public interface gowuchemodel { public void get(string uid, callback callback); }
model页面的代码:
public class mygowuchemodel implements gowuchemodel { @override public void get(string uid, callback callback) { hashmap<string, string> map = new hashmap<>(); map.put("uid", uid); okhttp3utils.dopost("http://120.27.23.105/product/getcarts?source=android", map, callback); } }
view页面的代码:
public interface gowucheview { public void success(shopbean bean); public void failuer(exception e); }
persenter页面的代码:
public class gowuchepersenter { gowucheview view; private final mygowuchemodel model; public gowuchepersenter(gowucheview view) { this.view = view; model = new mygowuchemodel(); } public void getdata(string uid) { model.get(uid, new onuicallback() { @override public void onfailed(call call, ioexception e) { if (view != null) { view.failuer(e); } } @override public void onsuccess(string result) { gson gson = new gson(); shopbean bean = gson.fromjson(result, shopbean.class); view.success(bean); } }); } public void saaa() { this.view = null; } }
mainactivity页面代码:
public class mainactivity extends appcompatactivity implements gowucheview { private gowuchepersenter persenter; private expandablelistview melv; /** * 全选 */ private checkbox mcb; /** * 合计: */ private textview mtvtotal; /** * 去结算(0) */ private textview mtvcount; private elvadapter elvadapter; list<shopbean.data> group = new arraylist<>(); list<list<shopbean.data.list>> child = new arraylist<>(); @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); initview(); persenter = new gowuchepersenter(this); persenter.getdata("99"); mcb.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { elvadapter.allornone(mcb.ischecked()); } }); } private void initview() { melv = (expandablelistview) findviewbyid(r.id.elv); mcb = (checkbox) findviewbyid(r.id.cb); mtvtotal = (textview) findviewbyid(r.id.tvtotal); mtvcount = (textview) findviewbyid(r.id.tvcount); } public void setpriceandcount(priceandcount priceandcount) { mtvtotal.settext("合计:" + priceandcount.getprice()); mtvcount.settext("去结算(" + priceandcount.getcount() + ")"); } public void setallchecked(boolean bool) { mcb.setchecked(bool); } @override public void success(shopbean bean) { for (int i = 0; i < bean.getdata().size(); i++) { group.add(bean.getdata().get(i)); } for (int i = 0; i < group.size(); i++) { child.add(bean.getdata().get(i).getlist()); } elvadapter = new elvadapter(this, group, child); melv.setgroupindicator(null); melv.setadapter(elvadapter); for (int i = 0; i < group.size(); i++) { melv.expandgroup(i); } } @override public void failuer(exception e) { } @override protected void ondestroy() { super.ondestroy(); persenter.saaa(); } }
adapter页面代码:
public class elvadapter extends baseexpandablelistadapter { private final layoutinflater inflater; private context context; private list<shopbean.data> group; private list<list<shopbean.data.list>> child; public elvadapter(context context, list<shopbean.data> group, list<list<shopbean.data.list>> child) { this.context = context; this.group = group; this.child = child; inflater = layoutinflater.from(context); } @override public int getgroupcount() { return group.size(); } @override public int getchildrencount(int groupposition) { return child.get(groupposition).size(); } @override public object getgroup(int groupposition) { return group.get(groupposition); } @override public object getchild(int groupposition, int childposition) { return child.get(groupposition).get(childposition); } @override public long getgroupid(int groupposition) { return groupposition; } @override public long getchildid(int groupposition, int childposition) { return childposition; } @override public boolean hasstableids() { return false; } @override public view getgroupview(final int groupposition, boolean isexpanded, view convertview, viewgroup parent) { view view; log.i("============", "getgroupview: "); final groupviewholder holder; if (convertview == null) { view = inflater.inflate(r.layout.elv_group, null); holder = new groupviewholder(); holder.tv = view.findviewbyid(r.id.tv_group); holder.cbgroup = view.findviewbyid(r.id.cb_group); view.settag(holder); } else { view = convertview; holder = (groupviewholder) view.gettag(); } final shopbean.data data = group.get(groupposition); holder.tv.settext(data.getsellername()); holder.cbgroup.setchecked(data.ischeck()); holder.cbgroup.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { //需要改变三个checkbox的状态值 //1.一级列表的checkbox的状态值 data.setcheck(holder.cbgroup.ischecked()); //二级列表的checkbox的状态值 setchildrencb(groupposition, holder.cbgroup.ischecked()); //全选的checkbox状态值 ((mainactivity) context).setallchecked(isallgroupcbchecked()); //计算钱和数量并显示 setpriceandcount(); //刷新界面 notifydatasetchanged(); } }); return view; } @override public view getchildview(final int groupposition, final int childposition, boolean islastchild, view convertview, viewgroup parent) { view view1; final childviewholder holder1; if (convertview == null) { view1 = inflater.inflate(r.layout.elv_child, null); holder1 = new childviewholder(); holder1.iv = view1.findviewbyid(r.id.iv); holder1.tvtitle = view1.findviewbyid(r.id.tv_title); holder1.tvsubhead = view1.findviewbyid(r.id.tvsubhead); holder1.tvprice = view1.findviewbyid(r.id.tvprice); holder1.cbchild = view1.findviewbyid(r.id.cb_child); holder1.btdel = view1.findviewbyid(r.id.btdel); holder1.tvnum = view1.findviewbyid(r.id.tvnum); holder1.ivdel = view1.findviewbyid(r.id.ivdel); holder1.ivadd = view1.findviewbyid(r.id.ivadd); view1.settag(holder1); } else { view1 = convertview; holder1 = (childviewholder) view1.gettag(); } final shopbean.data.list listbean = child.get(groupposition).get(childposition); string images = listbean.getimages(); glide.with(context).load(images.split("\\|")[0]).into(holder1.iv); holder1.tvtitle.settext(listbean.gettitle()); holder1.cbchild.setchecked(child.get(groupposition).get(childposition).ischecked()); holder1.tvsubhead.settext(listbean.getsubhead()); holder1.tvprice.settext(listbean.getprice() + "元"); holder1.tvnum.settext(listbean.getcount() + ""); holder1.cbchild.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { //需要改变三个checkbox的状态值 //2.二级列表的checkbox状态值 listbean.setchecked(holder1.cbchild.ischecked()); //1.一级列表的checkbox的状态值 group.get(groupposition).setcheck(isallchildcbchecked(groupposition)); //3.全选的checkbox状态值 ((mainactivity) context).setallchecked(isallgroupcbchecked()); //计算钱和数量并显示 setpriceandcount(); //刷新界面 notifydatasetchanged(); } }); //加一件商品 holder1.ivadd.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { int count = listbean.getcount(); count++; //改变javabean里的状态值 listbean.setcount(count); //计算钱和数量并显示 setpriceandcount(); //刷新列表 notifydatasetchanged(); } }); //减少一件商品 holder1.ivdel.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { int count = listbean.getcount(); if (count <= 1) { count = 1; } else { count--; } //改变javabean里的状态值 listbean.setcount(count); //计算钱和数量并显示 setpriceandcount(); //刷新列表 notifydatasetchanged(); } }); //删除 holder1.btdel.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { //其时就是删除集合 list<shopbean.data.list> listbeans = child.get(groupposition); if (listbeans.size() > 0) { listbeans.remove(childposition); } if (listbeans.size() == 0) { child.remove(groupposition); group.remove(groupposition); } //计算钱和数量并显示 setpriceandcount(); //改变全选状态 ((mainactivity) context).setallchecked(isallgroupcbchecked()); //刷新列表 notifydatasetchanged(); } }); return view1; } @override public boolean ischildselectable(int groupposition, int childposition) { return false; } /** * 设置一级列表对应的二级列表的checkbox状态 */ private void setchildrencb(int groupposition, boolean bool) { list<shopbean.data.list> listbeans = child.get(groupposition); for (int i = 0; i < listbeans.size(); i++) { listbeans.get(i).setchecked(bool); } } /** * 判断一级列表checkbox状态 */ private boolean isallgroupcbchecked() { if (group.size() == 0) { return false; } for (int i = 0; i < group.size(); i++) { if (!group.get(i).ischeck()) { return false; } } return true; } /** * 判断二级列表checkbox的状态 */ private boolean isallchildcbchecked(int groupposition) { list<shopbean.data.list> listbeans = child.get(groupposition); for (int i = 0; i < listbeans.size(); i++) { if (!listbeans.get(i).ischecked()) { return false; } } return true; } /** * 设置钱和数量 */ private void setpriceandcount(){ ((mainactivity)context).setpriceandcount(compute()); } /** * 计算钱和数量 */ private priceandcount compute(){ double price = 0; int count = 0; for (int i = 0; i < group.size(); i++) { list<shopbean.data.list> listbeans = child.get(i); for (int j = 0; j <listbeans.size() ; j++) { if(listbeans.get(j).ischecked()){ price+=listbeans.get(j).getprice()*listbeans.get(j).getcount(); count+=listbeans.get(j).getcount(); } } } return new priceandcount(price,count); } /** * 全选或者全不选 */ public void allornone(boolean bool){ for (int i = 0; i < group.size(); i++) { group.get(i).setcheck(bool); setchildrencb(i,bool); } setpriceandcount(); notifydatasetchanged(); } class groupviewholder { textview tv; checkbox cbgroup; } class childviewholder { imageview iv; textview tvtitle; textview tvsubhead; textview tvprice; checkbox cbchild; textview btdel; textview tvnum; imageview ivdel; imageview ivadd; } }
bean类代码:
创建一个priceandcount 代码
public class priceandcount { private double price; private int count; public priceandcount(double price, int count) { this.price = price; this.count = count; } public double getprice() { return price; } public void setprice(double price) { this.price = price; } public int getcount() { return count; } public void setcount(int count) { this.count = count; } }
bean类:
public class shopbean { /** * msg : 请求成功 * code : 0 * data : [{"list":[{"bargainprice":11800,"createtime":"2017-10-10t17:33:37","detailurl":"https://item.m.jd.com/product/4338107.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=qqfriends","images":"https://m.360buyimg.com/n0/jfs/t6700/155/2098998076/156185/6cf95035/595dd5a5nc3a7dab5.jpg!q70.jpg","num":1,"pid":57,"price":5199,"pscid":40,"selected":0,"sellerid":1,"subhead":"【i5 mx150 2g显存】全高清窄边框 8g内存 256固态硬盘 支持指纹识别 预装win10系统","title":"小米(mi)air 13.3英寸全金属轻薄笔记本(i5-7200u 8g 256g pcle ssd mx150 2g独显 fhd 指纹识别 win10)银\r\n"}],"sellername":"商家1","sellerid":"1"},{"list":[{"bargainprice":399,"createtime":"2017-10-02t15:20:02","detailurl":"https://item.m.jd.com/product/1439822107.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term=qqfriends","images":"https://m.360buyimg.com/n0/jfs/t5887/201/859509257/69994/6bde9bf6/59224c24ne854e14c.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5641/233/853609022/57374/5c73d281/59224c24n3324d5f4.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5641/233/853609022/57374/5c73d281/59224c24n3324d5f4.jpg!q70.jpg","num":2,"pid":81,"price":699,"pscid":85,"selected":0,"sellerid":2,"subhead":"满2件,总价打6.50折","title":"gap男装 休闲舒适简约水洗五袋直筒长裤紧身牛仔裤941825 深灰色 33/32(175/84a)"},{"bargainprice":11800,"createtime":"2017-10-14t21:38:26","detailurl":"https://item.m.jd.com/product/5025518.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=qqfriends","images":"https://m.360buyimg.com/n0/jfs/t8830/106/1760940277/195595/5cf9412f/59bf2ef5n5ab7dc16.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5428/70/1520969931/274676/b644dd0d/591128e7nd2f70da0.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5566/365/1519564203/36911/620c750c/591128ean54ac3363.jpg!q70.jpg","num":4,"pid":58,"price":6399,"pscid":40,"selected":0,"sellerid":2,"subhead":"升级4g大显存!nvme协议pcie ssd,速度快人一步】gtx1050ti就选拯救者!专业游戏键盘&新模具全新设计!","title":"联想(lenovo)拯救者r720 15.6英寸游戏笔记本电脑(i5-7300hq 8g 1t+128g ssd gtx1050ti 4g ips 黑)"}],"sellername":"商家2","sellerid":"2"},{"list":[{"bargainprice":11800,"createtime":"2017-10-14t21:48:08","detailurl":"https://mitem.jd.hk/ware/view.action?wareid=1988853309&cachekey=1acb07a701ece8d2434a6ae7fa6870a1","images":"https://m.360buyimg.com/n0/jfs/t6130/97/1370670410/180682/1109582a/593276b1nd81fe723.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5698/110/2617517836/202970/c9388feb/593276b7nbd94ef1f.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5698/110/2617517836/202970/c9388feb/593276b7nbd94ef1f.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5815/178/2614671118/51656/7f52d137/593276c7n107b725a.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5878/60/2557817477/30873/4502b606/593276can5a7d6357.jpg!q70.jpg","num":1,"pid":60,"price":13888,"pscid":40,"selected":0,"sellerid":4,"subhead":"购买电脑办公部分商品满1元返火车票5元优惠券(返完即止)","title":"全球购 新款apple macbook pro 苹果笔记本电脑 银色vp2新13英寸bar i5/8g/256g"}],"sellername":"商家4","sellerid":"4"},{"list":[{"bargainprice":111.99,"createtime":"2017-10-03t23:53:28","detailurl":"https://item.m.jd.com/product/4719303.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term=qqfriends","images":"https://m.360buyimg.com/n0/jfs/t9004/210/1160833155/647627/ad6be059/59b4f4e1n9a2b1532.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t7504/338/63721388/491286/f5957f53/598e95f1n7f2adb87.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t7441/10/64242474/419246/adb30a7d/598e95fbnd989ba0a.jpg!q70.jpg","num":1,"pid":3,"price":198,"pscid":1,"selected":0,"sellerid":19,"subhead":"每个中秋都不能简单,无论身在何处,你总需要一块饼让生活更圆满,京东月饼让爱更圆满京东自营,闪电配送,更多惊喜,快用手指戳一下","title":"北京稻香村 稻香村中秋节月饼 老北京月饼礼盒655g"}],"sellername":"商家19","sellerid":"19"}] */ private string msg; private string code; /** * list : [{"bargainprice":11800,"createtime":"2017-10-10t17:33:37","detailurl":"https://item.m.jd.com/product/4338107.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=qqfriends","images":"https://m.360buyimg.com/n0/jfs/t6700/155/2098998076/156185/6cf95035/595dd5a5nc3a7dab5.jpg!q70.jpg","num":1,"pid":57,"price":5199,"pscid":40,"selected":0,"sellerid":1,"subhead":"【i5 mx150 2g显存】全高清窄边框 8g内存 256固态硬盘 支持指纹识别 预装win10系统","title":"小米(mi)air 13.3英寸全金属轻薄笔记本(i5-7200u 8g 256g pcle ssd mx150 2g独显 fhd 指纹识别 win10)银\r\n"}] * sellername : 商家1 * sellerid : 1 */ private list<data> data; public void setmsg(string msg) { this.msg = msg; } public void setcode(string code) { this.code = code; } public void setdata(list<data> data) { this.data = data; } public string getmsg() { return msg; } public string getcode() { return code; } public list<data> getdata() { return data; } public static class data { public boolean ischeck() { return ischeck; } public void setcheck(boolean check) { ischeck = check; } private boolean ischeck; private string sellername; private string sellerid; /** * bargainprice : 11800.0 * createtime : 2017-10-10t17:33:37 * detailurl : * images : /595dd5a5nc3a7dab5.jpg!q70.jpg * num : 1 * pid : 57 * price : 5199.0 * pscid : 40 * selected : 0 * sellerid : 1 * subhead : 【i5 mx150 2g显存】全高清窄边框 8g内存 256固态硬盘 支持指纹识别 预装win10系统 * title : 小米(mi)air 13.3英寸全金属轻薄笔记本(i5-7200u 8g 256g pcle ssd mx150 2g独显 fhd 指纹识别 win10)银 */ private java.util.list<list> list; public void setsellername(string sellername) { this.sellername = sellername; } public void setsellerid(string sellerid) { this.sellerid = sellerid; } public void setlist(java.util.list<list> list) { this.list = list; } public string getsellername() { return sellername; } public string getsellerid() { return sellerid; } public java.util.list<list> getlist() { return list; } public static class list { private boolean ischecked; public boolean ischecked() { return ischecked; } public void setchecked(boolean checked) { ischecked = checked; } private int count; public int getcount() { return count; } public void setcount(int count) { this.count = count; } private double bargainprice; private string createtime; private string detailurl; private string images; private int num; private int pid; private double price; private int pscid; private int selected; private int sellerid; private string subhead; private string title; public void setbargainprice(double bargainprice) { this.bargainprice = bargainprice; } public void setcreatetime(string createtime) { this.createtime = createtime; } public void setdetailurl(string detailurl) { this.detailurl = detailurl; } public void setimages(string images) { this.images = images; } public void setnum(int num) { this.num = num; } public void setpid(int pid) { this.pid = pid; } public void setprice(double price) { this.price = price; } public void setpscid(int pscid) { this.pscid = pscid; } public void setselected(int selected) { this.selected = selected; } public void setsellerid(int sellerid) { this.sellerid = sellerid; } public void setsubhead(string subhead) { this.subhead = subhead; } public void settitle(string title) { this.title = title; } public double getbargainprice() { return bargainprice; } public string getcreatetime() { return createtime; } public string getdetailurl() { return detailurl; } public string getimages() { return images; } public int getnum() { return num; } public int getpid() { return pid; } public double getprice() { return price; } public int getpscid() { return pscid; } public int getselected() { return selected; } public int getsellerid() { return sellerid; } public string getsubhead() { return subhead; } public string gettitle() { return title; } } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
ExpandableListView实现简单二级列表
-
ExpandableListView实现二级列表购物车
-
完美实现ExpandableListView二级分栏效果
-
Android实现二级购物车的全选加反选、总价功能
-
Android基于BaseExpandableListAdapter实现的二级列表仿通话记录功能详解
-
【Python基础 | 列表】小实验:实现显示商品,选择商品,将商品加入购物车,得到总价格
-
ExpandableListView控件实现二级列表
-
jQuery结合PHP+MySQL实现二级联动下拉列表[实例]
-
Ajax实现列表无限加载和二级下拉选项效果
-
Vue+Node实现商品列表的分页、排序、筛选,添加购物车功能详解