Android仿淘宝购物车页面

    上面一篇博客介绍了在写一个类似于淘宝购物车页面的时候,使用ExpandableListView和BaseExpandableListAdapter的时候遇到的一些问题,这篇博客就来记录一下仿淘宝购物车页面具体是如何实现的。
    其实最主要的就是BaseExpandableListAdapter,activity中就只有一个ExpandableListView,和一个全选按钮,一个显示当前价格的TextView,在此就不贴出布局了,主要贴出adapter中是如何是实现的。
public class ShopBagExpandAdapter extends BaseExpandableListAdapter {
    /*
    这个是购物车的数据集,所有的数据都从这里来,这个数据集中包含一个商铺的List,每个商铺List里面又包含一个商品的List
    */
    private ShopBagGoodsListModel shopBagGoodsListModel = new ShopBagGoodsListModel();
    private Context context;
    //商品选择最小数量为1
    private static final int shopMinNum = 1;
    private ShopAllSelectListener shopAllSelectListener;//全选接口
    private PriceChangeListener priceChangeListener;//价格改变接口
    private PriceCaculatorErrorListener priceCaculatorErrorListener;//数据转换失败接口
    private DeleteGoodsInfoListener deleteGoodsInfoListener;//删除商品接口
    //使用map存储当前选中的商品,以便于计算价格,存放的是商品的id和商品内容
    private Map<String, ShopBagGoodsModel> selectGoodsMap = new HashMap<>();

    public ShopBagExpandAdapter(Context context, ExpandableListView expandableListView) {
        this.context = context;
        this.expandableListView = expandableListView;
    }

    public void setData(ShopBagGoodsListModel shopBagGoodsListModel) {
        this.shopBagGoodsListModel = shopBagGoodsListModel;

    }

    //在activity中对全选和取消全选的状态改变后调用这个方法
    public void setIsSelectAll(boolean isSelectAll) {
        //遍历所有的商铺和商店,设置为全选或者取消全选
        for (ShopBagStoreModel shopBagStoreModel : shopBagGoodsListModel.getGoods_list()) {
            shopBagStoreModel.setSelect(isSelectAll);
            for (ShopBagGoodsModel shopBagGoodsModel : shopBagStoreModel.getGoods_list()) {
                shopBagGoodsModel.setChecked(isSelectAll);
                //如果是全选,就把所有商品都加到map中去
                if (isSelectAll) {
                    selectGoodsMap.put(shopBagGoodsModel.getGoods_id(), shopBagGoodsModel);
                }
            }
        }
        //如果是取消全选,就把map中所有的数据清空
        if (!isSelectAll) {
            selectGoodsMap.clear();
        }
        //重新计算价格
        caculatorAllPrice();
        //刷新界面
        notifyDataSetChanged();

    }

    @Override
    public int getGroupCount() {
        if (shopBagGoodsListModel != null && shopBagGoodsListModel.getGoods_list() != null) {
            return shopBagGoodsListModel.getGoods_list().size();
        }
        return 0;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return shopBagGoodsListModel.getGoods_list().get(groupPosition).getGoods_list().size();
    }

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

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return shopBagGoodsListModel.getGoods_list().get(groupPosition).getGoods_list().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 true;
    }

    //父布局的view
    @Override
    public View getGroupView(final int i, boolean b, View view, ViewGroup viewGroup) {
        final GroupViewHolder groupViewHolder;
        if (view == null) {
            view = LayoutInflater.from(context).inflate(R.layout.adapter_shop_bag_store, null);
            groupViewHolder = new GroupViewHolder();
            groupViewHolder.storeSelect = view.findViewById(R.id.iv_adapter_shop_bag_store_select);
            groupViewHolder.storeName = view.findViewById(R.id.tv_adapter_shop_bag_store_name);
            view.setTag(groupViewHolder);
        } else {
            groupViewHolder = (GroupViewHolder) view.getTag();
        }
        groupViewHolder.storeSelect.setChecked(shopBagGoodsListModel.getGoods_list().get(i).isSelect());
        //如果父view是选中状态的话,那么防止出错,要设置子view,否则的话不理会
        if (shopBagGoodsListModel.getGoods_list().get(i).isSelect()) {
            for(ShopBagGoodsModel shopBagGoodsModel : shopBagGoodsListModel.getGoods_list().get(i).getGoods_list()){
                shopBagGoodsModel.setChecked(true);
            }
        }
        groupViewHolder.storeName.setText(shopBagGoodsListModel.getGoods_list().get(i).getRu_name());

        //点击店铺名称也可以对店铺的选中状态进行更改
        groupViewHolder.storeName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                boolean currentIsSelect = groupViewHolder.storeSelect.isChecked();
                groupViewHolder.storeSelect.setChecked(!currentIsSelect);
                shopBagGoodsListModel.getGoods_list().get(i).setSelect(!currentIsSelect);
                setChildViewSelect(i, !currentIsSelect);
                addStore(i,!currentIsSelect);
                notifyDataSetChanged();
            }
        });
        return view;
    }

    //子布局的view
    @Override
    public View getChildView(final int i, final int i1, boolean b, View view, ViewGroup viewGroup) {
        final ChildViewHolder childViewHolder;
        if (view == null) {
            view = LayoutInflater.from(context).inflate(R.layout.adapter_shop_bag_goods, null);
            childViewHolder = new ChildViewHolder();
            childViewHolder.shopSelect = view.findViewById(R.id.iv_adapter_shop_bag_goods_select);
            childViewHolder.shopImage = view.findViewById(R.id.iv_adapter_shop_bag_goods_product_img);
            childViewHolder.shopName = view.findViewById(R.id.tv_adapter_shop_bag_goods_product_about);
            childViewHolder.shopWeight = view.findViewById(R.id.tv_adapter_shop_bag_goods_product_weight);
            childViewHolder.shopPrice = view.findViewById(R.id.tv_adapter_shop_bag_goods_product_price);
            childViewHolder.shopLess = view.findViewById(R.id.tv_adapter_shop_bag_goods_minus);
            childViewHolder.shopNum = view.findViewById(R.id.tv_adapter_shop_bag_goods_num);
            childViewHolder.shopAdd = view.findViewById(R.id.tv_adapter_shop_bag_goods_add);
            //childViewHolder.shopDelete = view.findViewById(R.id.tv_adapter_shop_bag_goods_delete);
            childViewHolder.shopInfo = view.findViewById(R.id.ll_shop_info);
            view.setTag(childViewHolder);
        } else {
            childViewHolder = (ChildViewHolder) view.getTag();
        }
        /*
        * 设置子view的选中状态,根据父view去设置,如果父view设置了全选,那么子view就设置全选,否则根据用户的勾选来设置全选状态
        * */
        childViewHolder.shopSelect.setChecked(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).isChecked());
        //点击商品信息也是可以改变商品的选中状态的
        childViewHolder.shopInfo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                boolean childViewSelect = childViewHolder.shopSelect.isChecked();
                shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).setChecked(!childViewSelect);
                childViewHolder.shopSelect.setChecked(!childViewSelect);
                setGroupViewSelect(i, i1, !childViewSelect);
                addGood(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1),!childViewSelect);
                //更新界面
                notifyDataSetChanged();
            }
        });
        childViewHolder.shopSelect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                boolean childViewSelect = childViewHolder.shopSelect.isChecked();
                shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).setChecked(childViewSelect);
                childViewHolder.shopSelect.setChecked(childViewSelect);
                setGroupViewSelect(i, i1, childViewSelect);
                addGood(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1),childViewSelect);
                //更新界面
                notifyDataSetChanged();
            }
        });

        //长按商品信息可以删除一个商品
        childViewHolder.shopInfo.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                if(deleteGoodsInfoListener != null){
                    deleteGoodsInfoListener.deleteGoodsInfo(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1));
                }
                return false;
            }
        });
        //对商品数量添加和删除的修改
        //减少一个商品数量
        childViewHolder.shopLess.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    int currentNum = Integer.parseInt(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).getGoods_number());
                    if(currentNum <= shopMinNum){
                        Toast.makeText(context, "最少购买一件商品,长按可删除商品", Toast.LENGTH_SHORT).show();
                    }else{
                        shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).setGoods_number(String.valueOf(currentNum - 1));
                        childViewHolder.shopNum.setText(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).getGoods_number());
                        //重新计算价格
                        caculatorAllPrice();
                    }
                }catch (NumberFormatException exception){
                    Toast.makeText(context, "请稍后重试", Toast.LENGTH_SHORT).show();
                }

            }
            });
        //增加一个商品数量
        childViewHolder.shopAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    int currentNum = Integer.parseInt(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).getGoods_number());
                    shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).setGoods_number(String.valueOf(currentNum + 1));
                    childViewHolder.shopNum.setText(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).getGoods_number());
                    //重新计算价格
                    caculatorAllPrice();
                } catch (NumberFormatException exception) {
                    Toast.makeText(context, "请稍后重试", Toast.LENGTH_SHORT).show();
                }
            }
        });
        Glide.with(context)
                .load(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).getGoods_thumb())
                .into(childViewHolder.shopImage);
        childViewHolder.shopName.setText(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).getGoods_name());
        childViewHolder.shopWeight.setText(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).getTid());
        childViewHolder.shopPrice.setText(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).getMarket_price());
        childViewHolder.shopNum.setText(shopBagGoodsListModel.getGoods_list().get(i).getGoods_list().get(i1).getGoods_number());

        return view;
    }


    @Override
    public boolean isChildSelectable(int i, int i1) {

        return true;
    }

    class GroupViewHolder {
        public CheckBox storeSelect;
        public TextView storeName;
    }

    class ChildViewHolder {
        public CheckBox shopSelect;
        public ImageView shopImage;
        public TextView shopName;
        public TextView shopWeight;
        public TextView shopPrice;
        public TextView shopLess;
        public TextView shopNum;
        public TextView shopAdd;
        public TextView shopDelete;
        public LinearLayout shopInfo;
    }


    //设置子view的选中状态,如果父view的状态是选中的,那么子view应该是全部选中
    private void setChildViewSelect(int groupPosition, boolean isSelect) {
        //设置父布局下所有子布局的选中状态
        for (ShopBagGoodsModel shopBagGoodsModel : shopBagGoodsListModel.getGoods_list().get(groupPosition).getGoods_list()) {
            shopBagGoodsModel.setChecked(isSelect);
        }
        //设置完成之后查看是否所有的商铺都被选中
        for (int i = 0; i < shopBagGoodsListModel.getGoods_list().size(); i++) {
            if (!shopBagGoodsListModel.getGoods_list().get(i).isSelect()) {
                //有一个没被选中就不是选中状态
                if (shopAllSelectListener != null) {
                    shopAllSelectListener.shopAllSelect(false);
                    return;
                }
            }
        }
        //程序执行到此处说明所有的商铺都已经被选中了
        if (shopAllSelectListener != null) {
            shopAllSelectListener.shopAllSelect(true);
        }
    }

    //根据子view的状态设置父view的状态
    private void setGroupViewSelect(int groupPosition, int childPosition, boolean isSelect) {
        //当有一个子view被选中的时候,遍历查看是否当前子view所在布局下的所有view都被选中,如果都被选中的话,那么父view设置为选中状态,
        Log.i("TAG","当前的父view是:"+groupPosition+",子view是:"+childPosition);
        if (isSelect) {
            //当前有一个子view被选中,遍历父view
            for (ShopBagGoodsModel shopBagGoodsModel : shopBagGoodsListModel.getGoods_list().get(groupPosition).getGoods_list()) {
                if (!shopBagGoodsModel.isChecked()) {
                    //有一个子view不是处于选中状态,就说明当前父view不应该处于选中状态
                    shopBagGoodsListModel.getGoods_list().get(groupPosition).setSelect(false);
                    notifyDataSetChanged();
                    return;
                }

            }
            //遍历完成,说明所有的子view都处于选中状态,设置父view为选中状态
            shopBagGoodsListModel.getGoods_list().get(groupPosition).setSelect(true);
            //遍历查询是否所有的父布局都处于选中状态
            for (ShopBagStoreModel shopBagStoreModel : shopBagGoodsListModel.getGoods_list()) {
                if (!shopBagStoreModel.isSelect()) {
                    //有一个不是选中状态那就设置activity中为非全选状态
                    shopAllSelectListener.shopAllSelect(false);
                }
            }
            //所有的商铺都处于选中状态
            shopAllSelectListener.shopAllSelect(true);
        } else {
            //当前子view被设置为非选中状态,首先通知activity设置为非全选
            shopAllSelectListener.shopAllSelect(false);
            //设置子view所在父view为非选中状态
            shopBagGoodsListModel.getGoods_list().get(groupPosition).setSelect(false);
        }

    }

    //将某一个商店中所有的商品信息加入到map中,或者从map中去除当前商铺下所有商品信息
    private void addStore(int groupPosition, boolean isSelect) {
        if (isSelect) {
            //当前商铺被选中
            for (ShopBagGoodsModel shopBagGoodsModel : shopBagGoodsListModel.getGoods_list().get(groupPosition).getGoods_list()) {
                selectGoodsMap.put(shopBagGoodsModel.getGoods_id(), shopBagGoodsModel);
            }
        } else {
            Iterator iterator = selectGoodsMap.keySet().iterator();
            while (iterator.hasNext()) {
                String str = (String) iterator.next();
                for (ShopBagGoodsModel shopBagGoodsModel : shopBagGoodsListModel.getGoods_list().get(groupPosition).getGoods_list()) {
                    if (str.equals(shopBagGoodsModel.getGoods_id())) {
                        iterator.remove();
                        selectGoodsMap.remove(shopBagGoodsModel.getGoods_id());
                    }
                }
            }
        }
        caculatorAllPrice();
    }

    //将某一个商品添加到map中,或者从map中取出一个商品
    private void addGood(ShopBagGoodsModel shopBagGoodsModel, boolean isSelect){
        if(isSelect){
            //选中某个商品就加入到map中
            selectGoodsMap.put(shopBagGoodsModel.getGoods_id(),shopBagGoodsModel);
        }else{
            //如果map中存在这个商品,就取出来
            Iterator iterator = selectGoodsMap.keySet().iterator();
            while (iterator.hasNext()) {
                String str = (String) iterator.next();
                if(str.equals(shopBagGoodsModel.getGoods_id())){
                    iterator.remove();
                    selectGoodsMap.remove(shopBagGoodsModel.getGoods_id());
                }
            }
        }
        caculatorAllPrice();
    }

    //计算当前选中的商品总价
    private void caculatorAllPrice() {
        if (selectGoodsMap != null && selectGoodsMap.size() > 0) {
            //遍历计算每个商品的价格
            double totalPrice = 0.0;
            for (Map.Entry entry : selectGoodsMap.entrySet()) {
                ShopBagGoodsModel model = (ShopBagGoodsModel) entry.getValue();
                double currentPrice = 0.0;
                int currentNum = shopMinNum;
                try {
                    if (model.getMarket_price() != null && model.getMarket_price().length() > 0 && model.getMarket_price().contains("¥")) {
                        currentPrice = Double.parseDouble(model.getMarket_price().replace("¥", ""));
                    }
                    if (model.getGoods_number() != null && model.getGoods_number().length() > 0) {
                        currentNum = Integer.parseInt(model.getGoods_number());
                    }
                    //计算最后的价格
                    totalPrice += (currentPrice * currentNum);
                    //价格计算后保留两位小数
                    BigDecimal bigDecimal = new BigDecimal(totalPrice);
                    totalPrice = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                } catch (NumberFormatException exception) {
                    Log.i("TAG", "数字转换失败");
                    priceCaculatorErrorListener.priceCaculatorError();
                }
                priceChangeListener.nowPrice(totalPrice);
            }
        } else {
            priceChangeListener.nowPrice(0.0);
        }
    }

    //设置是否全选的接口
    public void setShopAllSelectListener(ShopAllSelectListener shopAllSelectListener) {
        this.shopAllSelectListener = shopAllSelectListener;
    }

    //商铺全选的接口
    public interface ShopAllSelectListener {
        void shopAllSelect(boolean selectAll);
    }

    //设置价格改变的接口
    public void setPriceChangeListener(PriceChangeListener priceChangeListener) {
        this.priceChangeListener = priceChangeListener;
    }

    //价格改变的接口,每次重新计算完价格之后都会调用这个接口,通知activity改变
    public interface PriceChangeListener {
        void nowPrice(double price);
    }


    public void setPriceCaculatorErrorListener(PriceCaculatorErrorListener priceCaculatorErrorListener) {
        this.priceCaculatorErrorListener = priceCaculatorErrorListener;
    }

    //当价格计算失败的时候结束当前页面,提醒用户重新进入该页面
    public interface PriceCaculatorErrorListener {
        void priceCaculatorError();
    }

    //设置用户删除商品接口
    public void setDeleteGoodsInfoListener(DeleteGoodsInfoListener deleteGoodsInfoListener){

        this.deleteGoodsInfoListener = deleteGoodsInfoListener;
    }

    //用户删除商品的接口
    public interface DeleteGoodsInfoListener{
        void deleteGoodsInfo(ShopBagGoodsModel shopBagGoodsModel);
    }
}
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值