购物车_简单实现基本功能_MVP框架_京东购物车效果

时间:2019-01-19
本文章向大家介绍购物车_简单实现基本功能_MVP框架_京东购物车效果,主要包括购物车_简单实现基本功能_MVP框架_京东购物车效果使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

购物车的基本介绍
购物车相当于现实中超市的购物车,不同的是一个是实体车,一个是虚拟车而已。用户可以在购物网站的不同页面之间跳转,以选购自己喜爱的商品,点击购买时,该商品就自动保存到你的购物车中,重复选购后,最后将选中的所有商品放在购物车中统一到付款台结账,这也是尽量让客户体验到现实生活中购物的感觉。服务器通过追踪每个用户的行动,以保证在结账时每件商品都物有其主。

我这次会把购物车源码给发出来,如果有需要的兄弟直接复制就行

购物车的功能包括以下几项:

1.把商品添加到购物车,即订购

2.删除购物车中已定购的商品

3.修改购物车中某一本图书的订购数量

4.显示购物车中商品清单及数量、价格

5.清空购物车

下面附上一张我自己做的购物车效果图

下面咱们就开始开始入手购物车功能点的实现
(1).先搭建个MVP的框架
(2).布局要清晰,要有逻辑
(3).实现功能点的步骤
(4).最后你要是感觉写的还行,给个赞O(∩_∩)O哈哈~

咱们先把功能点的布局写一下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/top_bar"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:orientation="vertical" >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:background="@android:color/transparent"
            android:orientation="vertical" >


            <TextView
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:minHeight="48dp"
                android:text="购物车"
                android:background="@mipmap/pizhi"
                android:textColor="#ff00"
                android:textSize="25sp" />

            <TextView
                android:id="@+id/subtitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_marginRight="12dp"
                android:gravity="center"
                android:minHeight="48dp"
                android:text=""
                android:textColor="#1a1a1a"
                android:textSize="14sp"
                android:visibility="visible" />
        </RelativeLayout>
    </LinearLayout>

    <ExpandableListView
        android:id="@+id/exListView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:childIndicator="@null"
        android:groupIndicator="@null" >
    </ExpandableListView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal"
        android:layout_marginBottom="@dimen/dp_60">

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2.5"
            android:gravity="center_vertical"
            android:orientation="horizontal" >

            <CheckBox
                android:id="@+id/all_chekbox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="4dp"
                android:checkMark="?android:attr/listChoiceIndicatorMultiple"
                android:gravity="center"
                android:minHeight="64dp"
                android:paddingLeft="10dp"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:visibility="visible" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:text="合计:"
                android:textSize="16sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/tv_total_price"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="¥0.00"
                android:textColor="@color/purple"
                android:textSize="16sp"
                android:textStyle="bold" />
        </LinearLayout>

        <TextView
            android:id="@+id/tv_delete"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/orange"
            android:clickable="true"
            android:gravity="center"
            android:text="删除"
            android:textColor="#FAFAFA" />

        <TextView
            android:id="@+id/tv_go_to_pay"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/crimson"
            android:clickable="true"
            android:gravity="center"
            android:text="结算(0)"
            android:textColor="#FAFAFA" />
    </LinearLayout>

</LinearLayout>

这个是店家的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white" >

        <CheckBox
            android:id="@+id/determine_chekbox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="4dp"
            android:checkMark="?android:attr/listChoiceIndicatorMultiple"
            android:gravity="center"
            android:minHeight="38dp"
            android:minWidth="32dp"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:visibility="visible" />

        <TextView
            android:id="@+id/tv_source_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginBottom="10dp"
            android:layout_marginTop="10dp"
            android:layout_toRightOf="@id/determine_chekbox"
            android:background="@android:color/white"
            android:drawablePadding="10dp"
            android:text="第八号当铺"
            android:textColor="@color/grey_color2"
            android:textSize="14sp" />
    </RelativeLayout>

</LinearLayout>

然后商品的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#CCCCCC" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/page_backgroup"
        android:orientation="horizontal" >

        <CheckBox
            android:id="@+id/check_box"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="4dp"
            android:checkMark="?android:attr/listChoiceIndicatorMultiple"
            android:gravity="center"
            android:minHeight="64dp"
            android:minWidth="32dp"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:visibility="visible" />

        <ImageView
            android:id="@+id/iv_adapter_list_pic"
            android:layout_width="85dp"
            android:layout_height="85dp"
            android:layout_marginBottom="15dp"
            android:layout_marginTop="13dp"
            android:scaleType="centerCrop"
            android:src="@drawable/ic_launcher_background" />

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginLeft="13dp" >

            <TextView
                android:id="@+id/tv_intro"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="10dp"
                android:layout_marginTop="20dp"
                android:ellipsize="end"
                android:maxLines="2"
                android:text="第八号当铺美女一枚"
                android:textColor="@color/grey_color1"
                android:textSize="14sp" />

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_marginBottom="30dp"
                android:orientation="horizontal" >

                <TextView
                    android:id="@+id/tv_price"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:singleLine="true"
                    android:text="¥ 308.00"
                    android:textColor="@color/orange_color"
                    android:textSize="14sp"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/tv_type_size"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_marginLeft="10dp"
                    android:layout_toRightOf="@+id/tv_price"
                    android:singleLine="true"
                    android:text="( 4L )"
                    android:textColor="@color/grey_color3"
                    android:textSize="10sp"
                    android:visibility="gone" />

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_centerVertical="true"
                    android:layout_marginRight="15dp"
                    android:orientation="horizontal" >

                    <TextView
                        android:id="@+id/tv_reduce"
                        android:layout_width="25dp"
                        android:layout_height="25dp"
                        android:gravity="center"
                        android:text="一"
                        android:textColor="@color/grey_color1"
                        android:textSize="12sp" />

                    <TextView
                        android:id="@+id/tv_num"
                        android:layout_width="25dp"
                        android:layout_height="25dp"
                        android:gravity="center"
                        android:singleLine="true"
                        android:text="1"
                        android:textColor="@color/grey_color1"
                        android:textSize="12sp" />

                    <TextView
                        android:id="@+id/tv_add"
                        android:layout_width="25dp"
                        android:layout_height="25dp"
                        android:gravity="center"
                        android:text="+"
                        android:textColor="@color/grey_color1"
                        android:textSize="12sp" />
                </LinearLayout>
            </RelativeLayout>
        </RelativeLayout>
    </LinearLayout>

</LinearLayout>

布局我们已经整完了,下面开始入手MVP框架的搭建
1.MVP的第一个步骤先写一个契约类,把V层接口,P层接口,M层接口给写一下
2.第二步创建P层的类,在P层中调用M层
3.最后在V层里实现效果

MVP的契约类

package gsp.com.dimensionbusiness.di.consentar;

public interface ShoppingContract {
    //V层
    public interface ShoppingView {
        //显示加载进度
        public void showLoading();

        //取消加载进度
        public void hideLoading();

        public void showData(String responseData);
    }

    //P层
    public interface ShoppingPrenser<ShoppingView> {
        //绑定
        public void attachData(ShoppingContract.ShoppingView shoppingView);

        //解绑
        public void dataData(ShoppingContract.ShoppingView shoppingView);

        //和M层进行交互
        public void resquesData();
    }
    //M层
    public interface ShoppingModel{
        //请求数据
        public void cantainData(Callback callback);

        //接口回调
        public interface Callback{

            //回显数据
            public void onCallback(String responseData);

        }
    }
}

P层的类

package gsp.com.dimensionbusiness.di.prenser;

import java.lang.ref.SoftReference;

import gsp.com.dimensionbusiness.di.consentar.ShoppingContract;
import gsp.com.dimensionbusiness.di.mdel.ShoppingModel;

public class ShopingPresenter implements ShoppingContract.ShoppingPrenser<ShoppingContract.ShoppingView> {
    ShoppingContract.ShoppingView shoppingView;
    private SoftReference<ShoppingContract.ShoppingView> softReference;
    private ShoppingModel shoppingModel;

    @Override
    public void attachData(ShoppingContract.ShoppingView shoppingView) {
        this.shoppingView=shoppingView;
        //创建软引用
        softReference = new SoftReference<>(shoppingView);
        //获取M层
        shoppingModel = new ShoppingModel();
    }

    @Override
    public void dataData(ShoppingContract.ShoppingView shoppingView) {
        softReference.clear();
    }

    @Override
    public void resquesData() {
       shoppingModel.cantainData(new ShoppingContract.ShoppingModel.Callback() {
           @Override
           public void onCallback(String responseData) {
               shoppingView.showData(responseData);
           }
       });
    }
}

M层的类

package gsp.com.dimensionbusiness.di.mdel;

import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.Response;

import gsp.com.dimensionbusiness.data.Contain;
import gsp.com.dimensionbusiness.di.consentar.ShoppingContract;

public class ShoppingModel implements ShoppingContract.ShoppingModel {
    @Override
    public void cantainData(final Callback callback) {
        //OkGo
        OkGo.<String>get(Contain.SHOPPINGCART_URL).execute(new StringCallback() {
            @Override
            public void onSuccess(Response<String> response) {
                String requestData = response.body().toString();
                callback.onCallback(requestData);
            }
        });
    }
}

我在这块插一句话啊,如果你是用接口解析数据,那么我下面的这个代码你得看看了,这个是我用的接口,我发布的这些接口不能用,因为我往里面加了点料 哈哈

package gsp.com.dimensionbusiness.data;

public class Contain {
    //登录
    public static final String LOGIN="http://mobile.bwstudent.com/small/big_user/v1/login";
    //注册
    public static final String REGISTER="http://mobile.bwstudent.com/small/big_user/v1/register";
    //轮播图
    public static final String IMAGEVIEW="http://mobile.bwstudent.com/small/comodity/v1/bannerShow";
    //首页商品接口
    public static final String HOMEPAGE="http://mobile.bwstudent.com/small/comodity/v1/commodityList";
    //购物车页接口
    public static final String SHOPPINGCART_URL = "https://www.zhaoapi.cn/produot/getCarts?uid=71";

}

V层的实现类

package gsp.com.dimensionbusiness.ui.fragment;


import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ExpandableListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import gsp.com.dimensionbusiness.R;
import gsp.com.dimensionbusiness.data.bean.GroupInfo;
import gsp.com.dimensionbusiness.data.bean.ProductInfo;
import gsp.com.dimensionbusiness.data.bean.Shoppingbean;
import gsp.com.dimensionbusiness.di.consentar.ShoppingContract;
import gsp.com.dimensionbusiness.di.prenser.ShopingPresenter;
import gsp.com.dimensionbusiness.ui.adapter.ShopcartExpandableListViewAdapter;

public class ThreeFragment extends Fragment implements ShopcartExpandableListViewAdapter.CheckInterface, ShopcartExpandableListViewAdapter.ModifyCountInterface, View.OnClickListener, ShoppingContract.ShoppingView {

    private ExpandableListView exListView;
    private CheckBox cb_check_all;
    private TextView tv_total_price;
    private TextView tv_delete;
    private TextView tv_go_to_pay;
    private Context context;

    private double totalPrice = 0.00;// 购买的商品总价
    private int totalCount = 0;// 购买的商品总数量

    private ShopcartExpandableListViewAdapter selva;
    private List<GroupInfo> groups = new ArrayList<GroupInfo>();// 组元素数据列表
    private Map<String, List<ProductInfo>> children = new HashMap<String, List<ProductInfo>>();// 子元素数据列表
    private List<Shoppingbean.DataBean> data;
    private View view;
    private ShopingPresenter shopingPresenter;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = View.inflate(getActivity(), R.layout.fragment_three, null);

        shopingPresenter = new ShopingPresenter();
        shopingPresenter.attachData(this);
        shopingPresenter.resquesData();
        context = getContext();
        exListView = (ExpandableListView) view.findViewById(R.id.exListView);
        cb_check_all = (CheckBox) view.findViewById(R.id.all_chekbox);
        tv_total_price = (TextView) view.findViewById(R.id.tv_total_price);
        tv_delete = (TextView) view.findViewById(R.id.tv_delete);
        tv_go_to_pay = (TextView) view.findViewById(R.id.tv_go_to_pay);
        return view;
    }


    private void initEvents() {
        selva = new ShopcartExpandableListViewAdapter(groups, children, context);
        selva.setCheckInterface(this);// 关键步骤1,设置复选框接口
        selva.setModifyCountInterface(this);// 关键步骤2,设置数量增减接口
        exListView.setAdapter(selva);

        for (int i = 0; i < selva.getGroupCount(); i++) {
            exListView.expandGroup(i);// 关键步骤3,初始化时,将ExpandableListView以展开的方式呈现
        }

        cb_check_all.setOnClickListener(this);
        tv_delete.setOnClickListener(this);
        tv_go_to_pay.setOnClickListener(this);
    }

    /**
     * 模拟数据<br>
     * 遵循适配器的数据列表填充原则,组元素被放在一个List中,对应的组元素下辖的子元素被放在Map中,<br>
     * 其键是组元素的Id(通常是一个唯一指定组元素身份的值)
     */
    private void virtualData() {

        for (int i = 0; i < data.size(); i++) {
            Shoppingbean.DataBean dataBean = data.get(i);
            String sellerName = dataBean.getSellerName();
            groups.add(new GroupInfo(i + "", sellerName));
            List<ProductInfo> products = new ArrayList<ProductInfo>();
            List<Shoppingbean.DataBean.ListBean> list = dataBean.getList();
            for (int j = 0; j < list.size(); j++) {
                Shoppingbean.DataBean.ListBean listBean = list.get(j);
                //Toast.makeText(context, "111111"+listBean.getImages(), Toast.LENGTH_SHORT).show();
                String images = listBean.getImages();
                String[] split = images.split("\\|");
                products.add(new ProductInfo(j + "", "商品", split[0], listBean.getTitle(), listBean.getPrice(), listBean.getNum()));

            }
            children.put(groups.get(i).getId(), products);// 将组元素的一个唯一值,这里取Id,作为子元素List的Key
        }
    }

    @Override
    public void onClick(View v) {
        AlertDialog alert;
        switch (v.getId()) {
            case R.id.all_chekbox:
                doCheckAll();
                calculate();
                break;
            case R.id.tv_go_to_pay:
                if (totalCount == 0) {
                    Toast.makeText(context, "请选择要支付的商品", Toast.LENGTH_LONG).show();
                    return;
                }
                alert = new AlertDialog.Builder(context).create();
                alert.setTitle("操作提示");
                alert.setMessage("总计:\n" + totalCount + "种商品\n" + totalPrice + "元");
                alert.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        return;
                    }
                });
                alert.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        return;
                    }
                });
                alert.show();
                break;
            case R.id.tv_delete:
                if (totalCount == 0) {
                    Toast.makeText(context, "请选择要移除的商品", Toast.LENGTH_LONG).show();
                    return;
                }
                alert = new AlertDialog.Builder(context).create();
                alert.setTitle("操作提示");
                alert.setMessage("您确定要将这些商品从购物车中移除吗?");
                alert.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        return;
                    }
                });
                alert.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        doDelete();
                    }
                });
                alert.show();
                break;
        }
    }

    /**
     * 删除操作<br>
     * 1.不要边遍历边删除,容易出现数组越界的情况<br>
     * 2.现将要删除的对象放进相应的列表容器中,待遍历完后,以removeAll的方式进行删除
     */
    protected void doDelete() {
        List<GroupInfo> toBeDeleteGroups = new ArrayList<GroupInfo>();// 待删除的组元素列表
        for (int i = 0; i < groups.size(); i++) {
            GroupInfo group = groups.get(i);
            if (group.isChoosed()) {

                toBeDeleteGroups.add(group);
            }
            List<ProductInfo> toBeDeleteProducts = new ArrayList<ProductInfo>();// 待删除的子元素列表
            List<ProductInfo> childs = children.get(group.getId());
            for (int j = 0; j < childs.size(); j++) {
                if (childs.get(j).isChoosed()) {
                    toBeDeleteProducts.add(childs.get(j));
                }
            }
            childs.removeAll(toBeDeleteProducts);

        }

        groups.removeAll(toBeDeleteGroups);

        selva.notifyDataSetChanged();
        calculate();
    }

    @Override
    public void doIncrease(int groupPosition, int childPosition, View showCountView, boolean isChecked) {

        ProductInfo product = (ProductInfo) selva.getChild(groupPosition, childPosition);
        int currentCount = product.getCount();
        currentCount++;
        product.setCount(currentCount);
        ((TextView) showCountView).setText(currentCount + "");

        selva.notifyDataSetChanged();
        calculate();
    }

    @Override
    public void doDecrease(int groupPosition, int childPosition, View showCountView, boolean isChecked) {

        ProductInfo product = (ProductInfo) selva.getChild(groupPosition, childPosition);
        int currentCount = product.getCount();
        if (currentCount == 1)
            return;
        currentCount--;

        product.setCount(currentCount);
        ((TextView) showCountView).setText(currentCount + "");

        selva.notifyDataSetChanged();
        calculate();
    }

    @Override
    public void checkGroup(int groupPosition, boolean isChecked) {
        GroupInfo group = groups.get(groupPosition);
        List<ProductInfo> childs = children.get(group.getId());
        for (int i = 0; i < childs.size(); i++) {
            childs.get(i).setChoosed(isChecked);
        }
        if (isAllCheck())
            cb_check_all.setChecked(true);
        else
            cb_check_all.setChecked(false);
        selva.notifyDataSetChanged();
        calculate();
    }

    @Override
    public void checkChild(int groupPosition, int childPosiTion, boolean isChecked) {
        boolean allChildSameState = true;// 判断改组下面的所有子元素是否是同一种状态
        GroupInfo group = groups.get(groupPosition);
        List<ProductInfo> childs = children.get(group.getId());
        for (int i = 0; i < childs.size(); i++) {
            if (childs.get(i).isChoosed() != isChecked) {
                allChildSameState = false;
                break;
            }
        }
        if (allChildSameState) {
            group.setChoosed(isChecked);// 如果所有子元素状态相同,那么对应的组元素被设为这种统一状态
        } else {
            group.setChoosed(false);// 否则,组元素一律设置为未选中状态
        }

        if (isAllCheck())
            cb_check_all.setChecked(true);
        else
            cb_check_all.setChecked(false);
        selva.notifyDataSetChanged();
        calculate();
    }

    private boolean isAllCheck() {

        for (GroupInfo group : groups) {
            if (!group.isChoosed())
                return false;

        }

        return true;
    }

    /**
     * 全选与反选
     */
    private void doCheckAll() {
        for (int i = 0; i < groups.size(); i++) {
            groups.get(i).setChoosed(cb_check_all.isChecked());
            GroupInfo group = groups.get(i);
            List<ProductInfo> childs = children.get(group.getId());
            for (int j = 0; j < childs.size(); j++) {
                childs.get(j).setChoosed(cb_check_all.isChecked());
            }
        }
        selva.notifyDataSetChanged();
    }

    /**
     * 统计操作<br>
     * 1.先清空全局计数器<br>
     * 2.遍历所有子元素,只要是被选中状态的,就进行相关的计算操作<br>
     * 3.给底部的textView进行数据填充
     */
    private void calculate() {
        totalCount = 0;
        totalPrice = 0.00;
        for (int i = 0; i < groups.size(); i++) {
            GroupInfo group = groups.get(i);
            List<ProductInfo> childs = children.get(group.getId());
            for (int j = 0; j < childs.size(); j++) {
                ProductInfo product = childs.get(j);
                if (product.isChoosed()) {
                    totalCount++;
                    totalPrice += product.getPrice() * product.getCount();
                }
            }
        }
        tv_total_price.setText("¥" + totalPrice);
        tv_go_to_pay.setText("去支付(" + totalCount + ")");
    }

    @Override
    public void showLoading() {

    }

    @Override
    public void hideLoading() {

    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        shopingPresenter.dataData(this);
    }

    @Override
    public void showData(String responseData) {
        Gson gson = new Gson();
        Shoppingbean shoppingbean = gson.fromJson(responseData, Shoppingbean.class);
        data = shoppingbean.getData();
        //Toast.makeText(context, "111", Toast.LENGTH_SHORT).show();
        //加载布局
        virtualData();
        initEvents();
    }
}

下面我把适配器给大家发布一下

package gsp.com.dimensionbusiness.ui.adapter;

import android.content.Context;
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 com.bumptech.glide.Glide;

import java.util.List;
import java.util.Map;

import gsp.com.dimensionbusiness.R;
import gsp.com.dimensionbusiness.data.bean.GroupInfo;
import gsp.com.dimensionbusiness.data.bean.ProductInfo;

public class ShopcartExpandableListViewAdapter extends BaseExpandableListAdapter {
    private List<GroupInfo> groups;
    private Map<String, List<ProductInfo>> children;
    private Context context;
    //HashMap<Integer, View> groupMap = new HashMap<Integer, View>();
    //HashMap<Integer, View> childrenMap = new HashMap<Integer, View>();
    private CheckInterface checkInterface;
    private ModifyCountInterface modifyCountInterface;

    /**
     * 构造函数
     *
     * @param groups   组元素列表
     * @param children 子元素列表
     * @param context
     */
    public ShopcartExpandableListViewAdapter(List<GroupInfo> groups, Map<String, List<ProductInfo>> children, Context context) {
        super();
        this.groups = groups;
        this.children = children;
        this.context = context;
    }

    public void setCheckInterface(CheckInterface checkInterface) {
        this.checkInterface = checkInterface;
    }

    public void setModifyCountInterface(ModifyCountInterface modifyCountInterface) {
        this.modifyCountInterface = modifyCountInterface;
    }

    @Override
    public int getGroupCount() {
        return groups.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        String groupId = groups.get(groupPosition).getId();
        return children.get(groupId).size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return groups.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        List<ProductInfo> childs = children.get(groups.get(groupPosition).getId());

        return childs.get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return 0;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return 0;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {

        GroupHolder gholder;
        if (convertView == null) {
            gholder = new GroupHolder();
            convertView = View.inflate(context, R.layout.item_shopcart_group, null);
            gholder.cb_check = (CheckBox) convertView.findViewById(R.id.determine_chekbox);
            gholder.tv_group_name = (TextView) convertView.findViewById(R.id.tv_source_name);
            //groupMap.put(groupPosition, convertView);
            convertView.setTag(gholder);
        } else {
            // convertView = groupMap.get(groupPosition);
            gholder = (GroupHolder) convertView.getTag();
        }
        final GroupInfo group = (GroupInfo) getGroup(groupPosition);
        if (group != null) {
            gholder.tv_group_name.setText(group.getName());
            gholder.cb_check.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v)

                {
                    group.setChoosed(((CheckBox) v).isChecked());
                    checkInterface.checkGroup(groupPosition, ((CheckBox) v).isChecked());// 暴露组选接口
                }
            });
            gholder.cb_check.setChecked(group.isChoosed());
        }
        return convertView;
    }

    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {

        final ChildHolder cholder;
        if (convertView == null) {
            cholder = new ChildHolder();
            convertView = View.inflate(context, R.layout.item_shopcart_product, null);
            cholder.cb_check = (CheckBox) convertView.findViewById(R.id.check_box);
            cholder.ivvv = convertView.findViewById(R.id.iv_adapter_list_pic);
            cholder.tv_product_desc = (TextView) convertView.findViewById(R.id.tv_intro);
            cholder.tv_price = (TextView) convertView.findViewById(R.id.tv_price);
            cholder.iv_increase = (TextView) convertView.findViewById(R.id.tv_add);
            cholder.iv_decrease = (TextView) convertView.findViewById(R.id.tv_reduce);
            cholder.tv_count = (TextView) convertView.findViewById(R.id.tv_num);
            // childrenMap.put(groupPosition, convertView);
            convertView.setTag(cholder);
        } else {
            // convertView = childrenMap.get(groupPosition);
            cholder = (ChildHolder) convertView.getTag();
        }
        final ProductInfo product = (ProductInfo) getChild(groupPosition, childPosition);

        if (product != null) {
            Glide.with(context).load(product.getImageUrl()).into(cholder.ivvv);
            cholder.tv_product_desc.setText(product.getDesc());
            cholder.tv_price.setText("¥" + product.getPrice() + "");
            cholder.tv_count.setText(product.getCount() + "");
            cholder.cb_check.setChecked(product.isChoosed());
            cholder.cb_check.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    product.setChoosed(((CheckBox) v).isChecked());
                    cholder.cb_check.setChecked(((CheckBox) v).isChecked());
                    checkInterface.checkChild(groupPosition, childPosition, ((CheckBox) v).isChecked());// 暴露子选接口
                }
            });
            cholder.iv_increase.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    modifyCountInterface.doIncrease(groupPosition, childPosition, cholder.tv_count, cholder.cb_check.isChecked());// 暴露增加接口
                }
            });
            cholder.iv_decrease.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    modifyCountInterface.doDecrease(groupPosition, childPosition, cholder.tv_count, cholder.cb_check.isChecked());// 暴露删减接口
                }
            });
        }
        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return false;
    }

    /**
     * 组元素绑定器
     */
    private class GroupHolder {
        CheckBox cb_check;
        TextView tv_group_name;
    }

    /**
     * 子元素绑定器
     */
    private class ChildHolder {
        CheckBox cb_check;
        ImageView ivvv;
        TextView tv_product_name;
        TextView tv_product_desc;
        TextView tv_price;
        TextView iv_increase;
        TextView tv_count;
        TextView iv_decrease;

    }

    /**
     * 复选框接口
     */
    public interface CheckInterface {
        /**
         * 组选框状态改变触发的事件
         *
         * @param groupPosition 组元素位置
         * @param isChecked     组元素选中与否
         */
        public void checkGroup(int groupPosition, boolean isChecked);

        /**
         * 子选框状态改变时触发的事件
         *
         * @param groupPosition 组元素位置
         * @param childPosition 子元素位置
         * @param isChecked     子元素选中与否
         */
        public void checkChild(int groupPosition, int childPosition, boolean isChecked);
    }

    /**
     * 改变数量的接口
     */
    public interface ModifyCountInterface {
        /**
         * 增加操作
         *
         * @param groupPosition 组元素位置
         * @param childPosition 子元素位置
         * @param showCountView 用于展示变化后数量的View
         * @param isChecked     子元素选中与否
         */
        public void doIncrease(int groupPosition, int childPosition, View showCountView, boolean isChecked);

        /**
         * 删减操作
         *
         * @param groupPosition 组元素位置
         * @param childPosition 子元素位置
         * @param showCountView 用于展示变化后数量的View
         * @param isChecked     子元素选中与否
         */
        public void doDecrease(int groupPosition, int childPosition, View showCountView, boolean isChecked);
    }

}

说实话我感觉我这篇博客发布的内容有点多
我还是会把剩下的内容发布,我发现有些博客只写一部分,剩下的就不写了,这是最恶心的

如果发现我代码没有发全,或者有不懂的,可以私聊我,我给你解释一下

最后发布非常可爱的图片