本文实例为大家分享了android实现简单购物车的具体代码,供大家参考,具体内容如下
这里我用到的都是android自带sdk中的资源,做了一个极其简单的购物车实现,总结购物车难点包含两个方面:
1、checkbox的联动:
全选框、商铺复选框以及商品复选框要做到滴水不漏的联动,我的经验是在监听多选框时尽量采用click事件,避免使用checkchange事件(因为它总是能在你意想不到的地方调用),全选框可以通过商品价格来判断,这个在代码中也有体现。
2、数据的联动和ui的联动:
适配器的都是在外部类创建,而总价格等控件都是在调用适配器的地方,这个要做到联动,最简单的方式必然就是接口的回调,熟练使用可以节省很多代码,提高编程效率。
再有一个比较容易出现问题的地方就在于,我们经常是首先更改数据,然后通知适配器刷新数据(notifydatasetchanged()),这里要注意的一点就是在更新数据的时候,一定确保更新的传递到适配器中的数据集合,否则会发现这个更新适配器的方法是无效的。
其他相关问题代码中均有体现,如果和我一样是一个编程小白,仔细阅读会有收获滴。
代码中没有添加自己的资源,逻辑都有实现就是ui丑了一点
activity_main:
<?xml version="1.0" encoding="utf-8"?> <linearlayout android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.bwie.test.test1025two.mainactivity"> <relativelayout android:layout_gravity="center_horizontal" android:background="@color/coloraccent" android:layout_width="match_parent" android:layout_height="50dp"> <textview android:textsize="38sp" android:gravity="center" android:textcolor="#fff" android:text="购物车" android:layout_width="match_parent" android:layout_height="wrap_content" /> <textview android:textcolor="#fff" android:textsize="38sp" android:layout_alignparentright="true" android:text="2" android:id="@+id/main_num" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </relativelayout> <expandablelistview android:layout_weight="1" android:id="@+id/expand_able_view" android:layout_width="match_parent" android:layout_height="match_parent"/> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content"> <checkbox android:layout_weight="1" android:id="@+id/main_check_all" android:text="全选" android:layout_width="0dp" android:layout_height="wrap_content" /> <textview android:id="@+id/main_price" android:gravity="center_horizontal" android:text="0" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <button android:id="@+id/btn_delete" android:background="#aaa" android:layout_weight="1" android:text="删除" android:layout_width="0dp" android:layout_height="wrap_content" /> <button android:id="@+id/btn_buy" android:background="#f99" android:layout_weight="1" android:text="购买" android:layout_width="0dp" android:layout_height="wrap_content" /> </linearlayout> </linearlayout>
group_item:
注:这里图了个简单,商铺名称我是通过设置checkbox的text来显示的,另外取消焦点是为了不影响二级列表的点击展开与收回子集列表
<?xml version="1.0" encoding="utf-8"?> <linearlayout android:orientation="horizontal" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <checkbox android:focusable="false" android:id="@+id/group_check" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </linearlayout>
child_item:
<?xml version="1.0" encoding="utf-8"?> <linearlayout android:orientation="horizontal" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <checkbox android:id="@+id/child_check" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <imageview android:id="@+id/child_img" android:scaletype="center" android:src="@mipmap/ic_launcher" android:layout_width="80dp" android:layout_height="80dp" /> <textview android:id="@+id/child_price" android:textsize="22sp" android:textcolor="@color/colorprimary" android:text="2888" android:layout_width="wrap_content" android:layout_height="80dp" /> <relativelayout android:layout_weight="1" android:layout_width="match_parent" android:layout_height="80dp"> <textview android:text="名字" android:id="@+id/child_name" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <linearlayout android:orientation="horizontal" android:layout_alignparentbottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content"> <textview android:id="@+id/child_jian" android:gravity="center_horizontal" android:text="—" android:layout_width="30dp" android:layout_height="30dp" /> <textview android:gravity="center_horizontal" android:text="2" android:id="@+id/child_num" android:layout_width="30dp" android:layout_height="30dp" /> <textview android:id="@+id/child_jia" android:gravity="center_horizontal" android:text="+" android:layout_width="30dp" android:layout_height="30dp" /> </linearlayout> </relativelayout> </linearlayout>
groupbean:
package com.bwie.test.test1025two; import java.util.arraylist; /** * created by zzw on 2017/10/25. */ public class group { private string name; private boolean check; private arraylist<child> children; public group(string name, boolean check,arraylist<child> children) { this.name = name; this.check = check; this.children = children; } public group() { } public string getname() { return name; } public void setname(string name) { this.name = name; } public boolean ischeck() { return check; } public void setcheck(boolean check) { this.check = check; } public void setchildren(arraylist<child> children){ this.children = children; } public arraylist<child> getchildren(){ return children; } @override public string tostring() { return "group{" + "name='" + name + '\'' + ", check=" + check + '}'; } }
childbean:
package com.bwie.test.test1025two; /** * created by zzw on 2017/10/25. */ public class child { private string name; private string img; private int num; private boolean check; private int price; public child(string name, string img, int num, boolean check, int price) { this.name = name; this.img = img; this.num = num; this.check = check; this.price = price; } public child() { } public string getname() { return name; } public void setname(string name) { this.name = name; } public string getimg() { return img; } public void setimg(string img) { this.img = img; } public int getnum() { return num; } public void setnum(int num) { this.num = num; } public boolean ischeck() { return check; } public void setcheck(boolean check) { this.check = check; } public int getprice() { return price; } public void setprice(int price) { this.price = price; } @override public string tostring() { return "child{" + "name='" + name + '\'' + ", img='" + img + '\'' + ", num=" + num + ", check=" + check + ", price=" + price + '}'; } }
myadapter:
package com.bwie.test.test1025two; import android.content.context; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.baseexpandablelistadapter; import android.widget.checkbox; import android.widget.imageview; import android.widget.textview; import java.util.arraylist; /** * created by zzw on 2017/10/25. */ public class myadapter extends baseexpandablelistadapter { context context; arraylist<group> groups; public myadapter(context context, arraylist<group> groups) { this.context = context; this.groups = groups; } //监听加减事件回调接口 public interface onnumchangelistener{ void onnumchange(int groupid,int childid,boolean isadd); } private onnumchangelistener monnumchangelistener; public void setonnumchangelistener(onnumchangelistener monnumchangelistener){ this.monnumchangelistener = monnumchangelistener; } //监听多选框点击事件回调接口。 public interface oncheckchangelistener{ void ongroupclick(int groupid); void onchildclick(int groupid,int childid); } private oncheckchangelistener moncheckchangelistener; public void setmoncheckchangelistener(oncheckchangelistener moncheckchangelistener){ this.moncheckchangelistener = moncheckchangelistener; } //监听价格需要更新回调接口 public interface onshouldchangemoneylistener{ void onshouldchnagemoney(); } private onshouldchangemoneylistener monshouldchangemoneylistener; public void setmonshouldchangemoneylistener(onshouldchangemoneylistener monshouldchangemoneylistener){ this.monshouldchangemoneylistener = monshouldchangemoneylistener; } @override public int getgroupcount() { return groups.size(); } @override public int getchildrencount(int i) { return groups.get(i).getchildren().size(); } @override public object getgroup(int i) { return groups.get(i); } @override public object getchild(int i, int i1) { return groups.get(i).getchildren().get(i1); } @override public long getgroupid(int i) { return i; } @override public long getchildid(int i, int i1) { return i1; } @override public boolean hasstableids() { return false; } @override public view getgroupview(final int i, boolean b, view view, viewgroup viewgroup) { groupholder holder = null; if (view == null){ view = layoutinflater.from(context).inflate(r.layout.group_item,viewgroup,false); holder = new groupholder(); holder.checkbox = (checkbox) view.findviewbyid(r.id.group_check); view.settag(holder); }else{ holder = (groupholder) view.gettag(); } holder.checkbox.settext(groups.get(i).getname()); holder.checkbox.setchecked(groups.get(i).ischeck()); if (moncheckchangelistener != null&&monshouldchangemoneylistener != null){ holder.checkbox.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { moncheckchangelistener.ongroupclick(i); monshouldchangemoneylistener.onshouldchnagemoney(); } }); } return view; } @override public view getchildview(final int i,final int i1, boolean b, view view, viewgroup viewgroup) { childholder holder = null; if (view == null){ view = layoutinflater.from(context).inflate(r.layout.child_item,viewgroup,false); holder = new childholder(); holder.checkbox = (checkbox) view.findviewbyid(r.id.child_check); holder.imageview = (imageview) view.findviewbyid(r.id.child_img); holder.name = (textview) view.findviewbyid(r.id.child_name); holder.num = (textview) view.findviewbyid(r.id.child_num); holder.jian = (textview) view.findviewbyid(r.id.child_jian); holder.jia = (textview) view.findviewbyid(r.id.child_jia); holder.price = (textview) view.findviewbyid(r.id.child_price); view.settag(holder); }else{ holder = (childholder) view.gettag(); } holder.checkbox.setchecked(groups.get(i).getchildren().get(i1).ischeck()); holder.imageview.setimageresource(r.mipmap.ic_launcher); holder.name.settext(groups.get(i).getchildren().get(i1).getname()); holder.num.settext(groups.get(i).getchildren().get(i1).getnum()+""); holder.price.settext(groups.get(i).getchildren().get(i1).getprice()+""); if (monnumchangelistener != null&&monshouldchangemoneylistener != null){ holder.jian.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { monnumchangelistener.onnumchange(i,i1,false); monshouldchangemoneylistener.onshouldchnagemoney(); } }); } if (monnumchangelistener != null&&monshouldchangemoneylistener != null){ holder.jia.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { monnumchangelistener.onnumchange(i,i1,true); monshouldchangemoneylistener.onshouldchnagemoney(); } }); } if (moncheckchangelistener != null&&monshouldchangemoneylistener != null){ holder.checkbox.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { moncheckchangelistener.onchildclick(i,i1); monshouldchangemoneylistener.onshouldchnagemoney(); } }); } return view; } @override public boolean ischildselectable(int i, int i1) { return true; } class groupholder { checkbox checkbox; } class childholder{ checkbox checkbox; imageview imageview; textview name,num,jian,jia,price; } }
mainactivity:
package com.bwie.test.test1025two; import android.os.bundle; import android.support.v7.app.appcompatactivity; import android.view.view; import android.widget.button; import android.widget.checkbox; import android.widget.expandablelistview; import android.widget.textview; import android.widget.toast; import java.util.arraylist; import java.util.list; public class mainactivity extends appcompatactivity { textview num,price;//右上角当前商品数量和底部当前已选中商品的价格 expandablelistview expandablelistview;//展示商品信息的二级列表 checkbox checkall;//左下角全选 button btndel,btnbuy;//底部删除当前选中按钮、购买按钮 arraylist<group> groups = new arraylist<>();//数据源集合 myadapter adapter;//自定义baseexpandable适配器 @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); initview();//控件初始化 initdata();//数据初始化 changegoodsnum();//初始化当前商品个数。 /** * 自定义加减按钮回调 * params: groupid:商铺id childid:商品在当前商铺的id isadd:非加即减 */ adapter.setonnumchangelistener(new myadapter.onnumchangelistener() { @override public void onnumchange(int groupid, int childid, boolean isadd) { //获得当前点击商品的数量 int num = groups.get(groupid).getchildren().get(childid).getnum(); if (isadd){//加 //在数据源中该商品数量自增1 groups.get(groupid).getchildren().get(childid).setnum(++num); }else{//减 if (num == 1){//数量为1给出提示 toast.maketext(mainactivity.this, "受不了了,不能再少了", toast.length_short).show(); }else{//在数据源中该商品数量自减1 groups.get(groupid).getchildren().get(childid).setnum(--num); } } //更新ui adapter.notifydatasetchanged(); changemoney();//更新价格显示 } }); //自定义商铺和商品多选框点击回调 adapter.setmoncheckchangelistener(new myadapter.oncheckchangelistener() { @override public void ongroupclick(int groupid) {//组点击 //将数据源置反,以保持同步 groups.get(groupid).setcheck(!(groups.get(groupid).ischeck())); //获取当前选中状态 boolean flag = groups.get(groupid).ischeck(); //更新其下所有商品checkbox for (int i = 0 ; i < groups.get(groupid).getchildren().size(); i++){ groups.get(groupid).getchildren().get(i).setcheck(flag); } //更新ui adapter.notifydatasetchanged(); //更新价格显示 changemoney(); } @override public void onchildclick(int groupid, int childid) {//商品点击 //将数据源置反以保持同步 groups.get(groupid).getchildren().get(childid).setcheck(!(groups.get(groupid).getchildren().get(childid).ischeck())); //判断该条目及所有兄弟条目是否全部选中,以及时更新商铺checkbox int flag = 0; for (int i = 0 ; i < groups.get(groupid).getchildren().size() ; i++){ if (groups.get(groupid).getchildren().get(i).ischeck()){ flag++; } } //如果该组下的选中数量与该集合长度相等,说明全部选中,更新组checkbox if (flag == groups.get(groupid).getchildren().size()){ groups.get(groupid).setcheck(true); }else{ groups.get(groupid).setcheck(false); } //更新ui adapter.notifydatasetchanged(); //更新价格显示 changemoney(); } }); //删除按钮点击 btndel.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { list<group> tobedeletegroups = new arraylist<group>();// 待删除的组元素列表 for (int i = 0; i < groups.size(); i++) { group group = groups.get(i); if (group.ischeck()) { tobedeletegroups.add(group); } list<child> tobedeletechildren = new arraylist<child>();// 待删除的子元素列表 list<child> childs = group.getchildren(); for (int j = 0; j < childs.size(); j++) { if (childs.get(j).ischeck()) { tobedeletechildren.add(childs.get(j)); } } childs.removeall(tobedeletechildren); } groups.removeall(tobedeletegroups); //更新ui adapter.notifydatasetchanged(); //更新当前商品数量显示 changegoodsnum(); //更新当前价格显示 changemoney(); } }); //购买按钮,点击提示当前选中金额 btnbuy.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { string money = price.gettext().tostring(); toast.maketext(mainactivity.this, "当前总金额:"+money, toast.length_short).show(); } }); //全选按钮,点击更新视图所有checkbox checkall.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { for (int i = 0 ; i< groups.size() ; i++){ groups.get(i).setcheck(checkall.ischecked()); for (int j = 0 ; j < groups.get(i).getchildren().size() ; j ++){ groups.get(i).getchildren().get(j).setcheck(checkall.ischecked()); } } //更新ui adapter.notifydatasetchanged(); //更新总价显示 changemoney(); } }); //自定义回调更新总价 adapter.setmonshouldchangemoneylistener(new myadapter.onshouldchangemoneylistener() { @override public void onshouldchnagemoney() { //更新总价显示 changemoney(); } }); } //初始化数据,设置适配器 private void initdata() { for (int i = 0 ; i < 5 ; i++){ arraylist<child> children = new arraylist<>(); for (int j = 0 ; j <= i ; j++){ children.add(new child("店铺"+i+"的商品:"+j,"",2,false,j+1)); } groups.add(new group("商铺:"+i,false,children)); } adapter = new myadapter(this,groups); expandablelistview.setadapter(adapter); for (int i = 0; i < groups.size(); i++) { expandablelistview.expandgroup(i);// 初始化时,将expandablelistview以展开的方式呈现 } } //获得控件资源 private void initview() { num = (textview) findviewbyid(r.id.main_num); expandablelistview = (expandablelistview) findviewbyid(r.id.expand_able_view); checkall = (checkbox) findviewbyid(r.id.main_check_all); btndel = (button) findviewbyid(r.id.btn_delete); btnbuy = (button) findviewbyid(r.id.btn_buy); price = (textview) findviewbyid(r.id.main_price); } //当前购物车商品数量 private void changegoodsnum(){ int currentnum = 0; for (int i = 0 ; i < groups.size(); i++){ for (int j = 0 ; j < groups.get(i).getchildren().size(); j++){ currentnum++; } } num.settext(currentnum+""); } //更新总价 private void changemoney(){ int money = 0; int allmoney = 0;//获得当前全部商品价格 for (int i = 0 ; i < groups.size(); i++){ for (int j = 0 ; j < groups.get(i).getchildren().size(); j++){ if (groups.get(i).getchildren().get(j).ischeck()){ money += groups.get(i).getchildren().get(j).getnum() * groups.get(i).getchildren().get(j).getprice(); } allmoney += groups.get(i).getchildren().get(j).getnum() * groups.get(i).getchildren().get(j).getprice(); } } //当选中价格与全部价格相等,更新全选框 if (money == allmoney){ checkall.setchecked(true); }else{ checkall.setchecked(false); } price.settext(money + ""); } }
效果图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。