本文实例为大家分享了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 + "");
    }
}

效果图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。