Android实现商城购物车功能
最近公司项目做商城模块,需要实现购物车功能,主要实现了单选、全选,金额合计,商品删除,商品数量加减等功能,先看看效果图:

一、实现步骤:
0、添加依赖库
1、购物车主界面布局文件(activity_main.xml)
2、购物车实现逻辑主界面(MainActivity.class)
3、使用ExpandableListView,继承BaseExpandableListAdapter
4、购物车数据的bean类(ShoppingCarDataBean.class)
5、分店铺实现布局
6、购物车中商品Item布局文件
二、实现过程:
0、添加依赖库
implementation 'com.jakewharton:butterknife:5.1.1'implementation 'com.google.code.gson:gson:2.2.4'implementation 'com.github.bumptech.glide:glide:3.7.0'
1、购物车主界面布局文件(activity_main.xml)
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#ffffff"android:orientation="vertical"><LinearLayoutandroid:id="@+id/ll_gouwuche"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#ededed"android:orientation="vertical"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="48dp"android:background="#ffffff"android:orientation="vertical"><ImageViewandroid:id="@+id/tv_titlebar_left"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_marginLeft="15dp"android:padding="5dp"android:src="@drawable/danghanglan_fanhui" /><TextViewandroid:id="@+id/tv_titlebar_center"android:layout_width="200dp"android:layout_height="match_parent"android:layout_centerHorizontal="true"android:ellipsize="end"android:gravity="center"android:maxLength="18"android:singleLine="true"android:text="购物车"android:textColor="#2f302b"android:textSize="17sp"android:visibility="visible" /><TextViewandroid:id="@+id/tv_titlebar_right"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_alignParentRight="true"android:background="@null"android:gravity="center"android:paddingLeft="15dp"android:paddingRight="15dp"android:singleLine="true"android:text="编辑"android:textColor="#2f302b"android:textSize="14sp"android:visibility="gone" /><Viewandroid:layout_width="match_parent"android:layout_height="0.5dp"android:layout_alignParentBottom="true"android:background="#cccccc" /></RelativeLayout><ExpandableListViewandroid:id="@+id/elv_shopping_car"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:background="#ededed"android:divider="@null"android:groupIndicator="@null"android:scrollbars="none"android:visibility="gone" /><RelativeLayoutandroid:id="@+id/rl"android:layout_width="match_parent"android:layout_height="54dp"android:background="#ffffff"android:visibility="gone"><LinearLayoutandroid:id="@+id/ll_select_all"android:layout_width="wrap_content"android:layout_height="match_parent"android:orientation="horizontal"android:paddingRight="10dp"><ImageViewandroid:id="@+id/iv_select_all"android:layout_width="20dp"android:layout_height="20dp"android:layout_gravity="center_vertical"android:layout_marginLeft="10dp"android:background="@drawable/gouwuche_unselect_bg" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginLeft="6dp"android:text="全选"android:textColor="#666666"android:textSize="12dp" /></LinearLayout><Buttonandroid:id="@+id/btn_order"android:layout_width="125dp"android:layout_height="40dp"android:layout_alignParentRight="true"android:layout_centerVertical="true"android:layout_marginRight="15dp"android:background="@drawable/jiarugouwuche_bg"android:text="结算"android:textColor="#ffffff"android:textSize="16dp"android:visibility="visible" /><Buttonandroid:id="@+id/btn_delete"android:layout_width="125dp"android:layout_height="40dp"android:layout_alignParentRight="true"android:layout_centerVertical="true"android:layout_marginRight="15dp"android:background="@drawable/jiarugouwuche_bg"android:text="删除"android:textColor="#ffffff"android:textSize="16dp"android:visibility="gone" /><RelativeLayoutandroid:id="@+id/rl_total_price"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_toLeftOf="@id/btn_order"android:layout_toRightOf="@id/ll_select_all"><TextViewandroid:id="@+id/tv_total_price"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_centerVertical="true"android:layout_marginLeft="2dp"android:layout_marginRight="10dp"android:maxLength="12"android:singleLine="true"android:text="¥0.00"android:textColor="#d8b691"android:textSize="15dp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_toLeftOf="@id/tv_total_price"android:text="合计金额:"android:textColor="#555555"android:textSize="13dp" /></RelativeLayout><Viewandroid:layout_width="match_parent"android:layout_height="0.5dp"android:background="#cccccc" /></RelativeLayout></LinearLayout><RelativeLayoutandroid:id="@+id/rl_no_contant"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:visibility="gone"><ImageViewandroid:id="@+id/iv_no_contant"android:layout_width="100dp"android:layout_height="100dp"android:layout_centerHorizontal="true"android:scaleType="centerCrop"android:src="@drawable/kong_gouwuche" /><TextViewandroid:layout_width="200dp"android:layout_height="wrap_content"android:layout_below="@+id/iv_no_contant"android:layout_marginTop="20dp"android:gravity="center"android:text="购物车竟然是空的"android:textColor="#808080"android:textSize="16dp" /></RelativeLayout></RelativeLayout>
2、购物车实现逻辑主界面(MainActivity.class)
/*** 购物车实现* 主要功能:* 1.单选、全选;* 2.合计;* 3.删除;* 4.商品数量加减;*/public class MainActivity extends AppCompatActivity {@InjectView(R.id.tv_titlebar_center)TextView tvTitlebarCenter;@InjectView(R.id.tv_titlebar_right)TextView tvTitlebarRight;@InjectView(R.id.elv_shopping_car)ExpandableListView elvShoppingCar;@InjectView(R.id.iv_select_all)ImageView ivSelectAll;@InjectView(R.id.ll_select_all)LinearLayout llSelectAll;@InjectView(R.id.btn_order)Button btnOrder;@InjectView(R.id.btn_delete)Button btnDelete;@InjectView(R.id.tv_total_price)TextView tvTotalPrice;@InjectView(R.id.rl_total_price)RelativeLayout rlTotalPrice;@InjectView(R.id.rl)RelativeLayout rl;@InjectView(R.id.iv_no_contant)ImageView ivNoContant;@InjectView(R.id.rl_no_contant)RelativeLayout rlNoContant;@InjectView(R.id.tv_titlebar_left)ImageView tvTitlebarLeft;//模拟的购物车数据(实际开发中使用后台返回的数据)private String shoppingCarData = "{\n" +" \"code\": 200,\n" +" \"datas\": [\n" +" {\n" +" \"goods\": [\n" +" {\n" +" \"goods_id\": \"111111\",\n" +" \"goods_image\": \"http://pic.58pic.com/58pic/15/62/69/34K58PICbmZ_1024.jpg\",\n" +" \"goods_name\": \"三国演义\",\n" +" \"goods_num\": \"2\",\n" +" \"goods_price\": \"15.00\"\n" +" }\n" +" ],\n" +" \"store_id\": \"1\",\n" +" \"store_name\": \"书店杂货铺\"\n" +" },\n" +" {\n" +" \"goods\": [\n" +" {\n" +" \"goods_id\": \"222221\",\n" +" \"goods_image\": \"http://file06.16sucai.com/2016/0511/9711205e4c003182edeed83355e6f1c7.jpg\",\n" +" \"goods_name\": \"西游记\",\n" +" \"goods_num\": \"2\",\n" +" \"goods_price\": \"12.00\"\n" +" },\n" +" {\n" +" \"goods_id\": \"222222\",\n" +" \"goods_image\": \"http://img01.taopic.com/150424/240473-1504240U13615.jpg\",\n" +" \"goods_name\": \"封神榜\",\n" +" \"goods_num\": \"1\",\n" +" \"goods_price\": \"28.00\"\n" +" }\n" +" ],\n" +" \"store_id\": \"2\",\n" +" \"store_name\": \"亚马逊书店\"\n" +" },\n" +" {\n" +" \"goods\": [\n" +" {\n" +" \"goods_id\": \"333331\",\n" +" \"goods_image\": \"http://pic22.nipic.com/20120718/8002769_100147127333_2.jpg\",\n" +" \"goods_name\": \"水浒传\",\n" +" \"goods_num\": \"3\",\n" +" \"goods_price\": \"18.00\"\n" +" },\n" +" {\n" +" \"goods_id\": \"333332\",\n" +" \"goods_image\": \"http://pic.58pic.com/58pic/14/71/50/40e58PICy54_1024.jpg\",\n" +" \"goods_name\": \"封神演义\",\n" +" \"goods_num\": \"3\",\n" +" \"goods_price\": \"32.00\"\n" +" },\n" +" {\n" +" \"goods_id\": \"333333\",\n" +" \"goods_image\": \"http://img01.taopic.com/150518/318750-15051PS40671.jpg\",\n" +" \"goods_name\": \"轩辕剑\",\n" +" \"goods_num\": \"3\",\n" +" \"goods_price\": \"3.80\"\n" +" }\n" +" ],\n" +" \"store_id\": \"3\",\n" +" \"store_name\": \"三味书屋\"\n" +" }\n" +" ]\n" +"}";private List<ShoppingCarDataBean.DatasBean> datas;private Context context;private ShoppingCarAdapter shoppingCarAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.inject(this);context = this;initExpandableListView();initData();}@OnClick({R.id.tv_titlebar_left, R.id.tv_titlebar_right})public void onViewClicked(View view) {switch (view.getId()) {case R.id.tv_titlebar_left://刷新数据initData();break;case R.id.tv_titlebar_right://编辑String edit = tvTitlebarRight.getText().toString().trim();if (edit.equals("编辑")) {tvTitlebarRight.setText("完成");rlTotalPrice.setVisibility(View.GONE);btnOrder.setVisibility(View.GONE);btnDelete.setVisibility(View.VISIBLE);} else {tvTitlebarRight.setText("编辑");rlTotalPrice.setVisibility(View.VISIBLE);btnOrder.setVisibility(View.VISIBLE);btnDelete.setVisibility(View.GONE);}break;default:break;}}/*** 初始化数据*/private void initData() {//使用Gson解析购物车数据,//ShoppingCarDataBean为bean类,Gson按照bean类的格式解析数据/*** 实际开发中,通过请求后台接口获取购物车数据并解析*/Gson gson = new Gson();ShoppingCarDataBean shoppingCarDataBean = gson.fromJson(shoppingCarData, ShoppingCarDataBean.class);datas = shoppingCarDataBean.getDatas();initExpandableListViewData(datas);}/*** 初始化ExpandableListView* 创建数据适配器adapter,并进行初始化操作*/private void initExpandableListView() {shoppingCarAdapter = new ShoppingCarAdapter(context, llSelectAll, ivSelectAll, btnOrder, btnDelete, rlTotalPrice, tvTotalPrice);elvShoppingCar.setAdapter(shoppingCarAdapter);//删除的回调shoppingCarAdapter.setOnDeleteListener(new ShoppingCarAdapter.OnDeleteListener() {@Overridepublic void onDelete() {initDelete();/*** 实际开发中,在此请求删除接口,删除成功后,* 通过initExpandableListViewData()方法刷新购物车数据。* 注:通过bean类中的DatasBean的isSelect_shop属性,判断店铺是否被选中;* GoodsBean的isSelect属性,判断商品是否被选中,* (true为选中,false为未选中)*/}});//修改商品数量的回调shoppingCarAdapter.setOnChangeCountListener(new ShoppingCarAdapter.OnChangeCountListener() {@Overridepublic void onChangeCount(String goods_id) {/*** 实际开发中,在此请求修改商品数量的接口,商品数量修改成功后,* 通过initExpandableListViewData()方法刷新购物车数据。*/}});}/*** 初始化ExpandableListView的数据* 并在数据刷新时,页面保持当前位置** @param datas 购物车的数据*/private void initExpandableListViewData(List<ShoppingCarDataBean.DatasBean> datas) {if (datas != null && datas.size() > 0) {//刷新数据时,保持当前位置shoppingCarAdapter.setData(datas);//使所有组展开for (int i = 0; i < shoppingCarAdapter.getGroupCount(); i++) {elvShoppingCar.expandGroup(i);}//使组点击无效果elvShoppingCar.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {@Overridepublic boolean onGroupClick(ExpandableListView parent, View v,int groupPosition, long id) {return true;}});tvTitlebarRight.setVisibility(View.VISIBLE);tvTitlebarRight.setText("编辑");rlNoContant.setVisibility(View.GONE);elvShoppingCar.setVisibility(View.VISIBLE);rl.setVisibility(View.VISIBLE);rlTotalPrice.setVisibility(View.VISIBLE);btnOrder.setVisibility(View.VISIBLE);btnDelete.setVisibility(View.GONE);} else {tvTitlebarRight.setVisibility(View.GONE);rlNoContant.setVisibility(View.VISIBLE);elvShoppingCar.setVisibility(View.GONE);rl.setVisibility(View.GONE);}}/*** 判断是否要弹出删除的dialog* 通过bean类中的DatasBean的isSelect_shop属性,判断店铺是否被选中;* GoodsBean的isSelect属性,判断商品是否被选中,*/private void initDelete() {//判断是否有店铺或商品被选中//true为有,则需要刷新数据;反之,则不需要;boolean hasSelect = false;//创建临时的List,用于存储没有被选中的购物车数据List<ShoppingCarDataBean.DatasBean> datasTemp = new ArrayList<>();for (int i = 0; i < datas.size(); i++) {List<ShoppingCarDataBean.DatasBean.GoodsBean> goods = datas.get(i).getGoods();boolean isSelect_shop = datas.get(i).getIsSelect_shop();if (isSelect_shop) {hasSelect = true;//跳出本次循环,继续下次循环。continue;} else {datasTemp.add(datas.get(i));datasTemp.get(datasTemp.size() - 1).setGoods(new ArrayList<ShoppingCarDataBean.DatasBean.GoodsBean>());}for (int y = 0; y < goods.size(); y++) {ShoppingCarDataBean.DatasBean.GoodsBean goodsBean = goods.get(y);boolean isSelect = goodsBean.getIsSelect();if (isSelect) {hasSelect = true;} else {datasTemp.get(datasTemp.size() - 1).getGoods().add(goodsBean);}}}if (hasSelect) {showDeleteDialog(datasTemp);} else {ToastUtil.makeText(context, "请选择要删除的商品");}}/*** 展示删除的dialog(可以自定义弹窗,不用删除即可)** @param datasTemp*/private void showDeleteDialog(final List<ShoppingCarDataBean.DatasBean> datasTemp) {View view = View.inflate(context, R.layout.dialog_two_btn, null);final RoundCornerDialog roundCornerDialog = new RoundCornerDialog(context, 0, 0, view, R.style.RoundCornerDialog);roundCornerDialog.show();roundCornerDialog.setCanceledOnTouchOutside(false);// 设置点击屏幕Dialog不消失roundCornerDialog.setOnKeyListener(keylistener);//设置点击返回键Dialog不消失TextView tv_message = view.findViewById(R.id.tv_message);TextView tv_logout_confirm = view.findViewById(R.id.tv_logout_confirm);TextView tv_logout_cancel = view.findViewById(R.id.tv_logout_cancel);tv_message.setText("确定要删除商品吗?");//确定tv_logout_confirm.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {roundCornerDialog.dismiss();datas = datasTemp;initExpandableListViewData(datas);}});//取消tv_logout_cancel.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {roundCornerDialog.dismiss();}});}DialogInterface.OnKeyListener keylistener = new DialogInterface.OnKeyListener() {public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {return true;} else {return false;}}};}
3、使用ExpandableListView,继承BaseExpandableListAdapter
/*** 购物车的adapter* 因为使用的是ExpandableListView,所以继承BaseExpandableListAdapter*/public class ShoppingCarAdapter extends BaseExpandableListAdapter {private final Context context;private final LinearLayout llSelectAll;private final ImageView ivSelectAll;private final Button btnOrder;private final Button btnDelete;private final RelativeLayout rlTotalPrice;private final TextView tvTotalPrice;private List<ShoppingCarDataBean.DatasBean> data;private boolean isSelectAll = false;private double total_price;public ShoppingCarAdapter(Context context, LinearLayout llSelectAll,ImageView ivSelectAll, Button btnOrder, Button btnDelete,RelativeLayout rlTotalPrice, TextView tvTotalPrice) {this.context = context;this.llSelectAll = llSelectAll;this.ivSelectAll = ivSelectAll;this.btnOrder = btnOrder;this.btnDelete = btnDelete;this.rlTotalPrice = rlTotalPrice;this.tvTotalPrice = tvTotalPrice;}/*** 自定义设置数据方法;* 通过notifyDataSetChanged()刷新数据,可保持当前位置** @param data 需要刷新的数据*/public void setData(List<ShoppingCarDataBean.DatasBean> data) {this.data = data;notifyDataSetChanged();}@Overridepublic int getGroupCount() {if (data != null && data.size() > 0) {return data.size();} else {return 0;}}@Overridepublic Object getGroup(int groupPosition) {return data.get(groupPosition);}@Overridepublic long getGroupId(int groupPosition) {return groupPosition;}@Overridepublic View getGroupView(final int groupPosition, final boolean isExpanded, View convertView, ViewGroup parent) {GroupViewHolder groupViewHolder;if (convertView == null) {convertView = View.inflate(context, R.layout.item_shopping_car_group, null);groupViewHolder = new GroupViewHolder(convertView);convertView.setTag(groupViewHolder);} else {groupViewHolder = (GroupViewHolder) convertView.getTag();}final ShoppingCarDataBean.DatasBean datasBean = data.get(groupPosition);//店铺IDString store_id = datasBean.getStore_id();//店铺名称String store_name = datasBean.getStore_name();if (store_name != null) {groupViewHolder.tvStoreName.setText(store_name);} else {groupViewHolder.tvStoreName.setText("");}//店铺内的商品都选中的时候,店铺的也要选中for (int i = 0; i < datasBean.getGoods().size(); i++) {ShoppingCarDataBean.DatasBean.GoodsBean goodsBean = datasBean.getGoods().get(i);boolean isSelect = goodsBean.getIsSelect();if (isSelect) {datasBean.setIsSelect_shop(true);} else {datasBean.setIsSelect_shop(false);break;}}//因为set之后要重新get,所以这一块代码要放到一起执行//店铺是否在购物车中被选中final boolean isSelect_shop = datasBean.getIsSelect_shop();if (isSelect_shop) {groupViewHolder.ivSelect.setImageResource(R.drawable.xuanze_xuanzhong);} else {groupViewHolder.ivSelect.setImageResource(R.drawable.unselect);}//店铺选择框的点击事件groupViewHolder.ll.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {datasBean.setIsSelect_shop(!isSelect_shop);List<ShoppingCarDataBean.DatasBean.GoodsBean> goods = datasBean.getGoods();for (int i = 0; i < goods.size(); i++) {ShoppingCarDataBean.DatasBean.GoodsBean goodsBean = goods.get(i);goodsBean.setIsSelect(!isSelect_shop);}notifyDataSetChanged();}});//当所有的选择框都是选中的时候,全选也要选中w:for (int i = 0; i < data.size(); i++) {List<ShoppingCarDataBean.DatasBean.GoodsBean> goods = data.get(i).getGoods();for (int y = 0; y < goods.size(); y++) {ShoppingCarDataBean.DatasBean.GoodsBean goodsBean = goods.get(y);boolean isSelect = goodsBean.getIsSelect();if (isSelect) {isSelectAll = true;} else {isSelectAll = false;break w;//根据标记,跳出嵌套循环}}}if (isSelectAll) {ivSelectAll.setBackgroundResource(R.drawable.xuanze_xuanzhong);} else {ivSelectAll.setBackgroundResource(R.drawable.unselect);}//全选的点击事件llSelectAll.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {isSelectAll = !isSelectAll;if (isSelectAll) {for (int i = 0; i < data.size(); i++) {List<ShoppingCarDataBean.DatasBean.GoodsBean> goods = data.get(i).getGoods();for (int y = 0; y < goods.size(); y++) {ShoppingCarDataBean.DatasBean.GoodsBean goodsBean = goods.get(y);goodsBean.setIsSelect(true);}}} else {for (int i = 0; i < data.size(); i++) {List<ShoppingCarDataBean.DatasBean.GoodsBean> goods = data.get(i).getGoods();for (int y = 0; y < goods.size(); y++) {ShoppingCarDataBean.DatasBean.GoodsBean goodsBean = goods.get(y);goodsBean.setIsSelect(false);}}}notifyDataSetChanged();}});//合计的计算total_price = 0.0;tvTotalPrice.setText("¥0.00");for (int i = 0; i < data.size(); i++) {List<ShoppingCarDataBean.DatasBean.GoodsBean> goods = data.get(i).getGoods();for (int y = 0; y < goods.size(); y++) {ShoppingCarDataBean.DatasBean.GoodsBean goodsBean = goods.get(y);boolean isSelect = goodsBean.getIsSelect();if (isSelect) {String num = goodsBean.getGoods_num();String price = goodsBean.getGoods_price();double v = Double.parseDouble(num);double v1 = Double.parseDouble(price);total_price = total_price + v * v1;//让Double类型完整显示,不用科学计数法显示大写字母EDecimalFormat decimalFormat = new DecimalFormat("0.00");tvTotalPrice.setText("¥" + decimalFormat.format(total_price));}}}//去结算的点击事件btnOrder.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//创建临时的List,用于存储被选中的商品List<ShoppingCarDataBean.DatasBean.GoodsBean> temp = new ArrayList<>();for (int i = 0; i < data.size(); i++) {List<ShoppingCarDataBean.DatasBean.GoodsBean> goods = data.get(i).getGoods();for (int y = 0; y < goods.size(); y++) {ShoppingCarDataBean.DatasBean.GoodsBean goodsBean = goods.get(y);boolean isSelect = goodsBean.getIsSelect();if (isSelect) {temp.add(goodsBean);}}}if (temp != null && temp.size() > 0) {//如果有被选中的/*** 实际开发中,如果有被选中的商品,* 则跳转到确认订单页面,完成后续订单流程。*/ToastUtil.makeText(context, "跳转到确认订单页面,完成后续订单流程");} else {ToastUtil.makeText(context, "请选择要购买的商品");}}});//删除的点击事件btnDelete.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {/*** 实际开发中,通过回调请求后台接口实现删除操作*/if (mDeleteListener != null) {mDeleteListener.onDelete();}}});return convertView;}static class GroupViewHolder {@InjectView(R.id.iv_select)ImageView ivSelect;@InjectView(R.id.tv_store_name)TextView tvStoreName;@InjectView(R.id.ll)LinearLayout ll;GroupViewHolder(View view) {ButterKnife.inject(this, view);}}//------------------------------------------------------------------------------------------------@Overridepublic int getChildrenCount(int groupPosition) {if (data.get(groupPosition).getGoods() != null && data.get(groupPosition).getGoods().size() > 0) {return data.get(groupPosition).getGoods().size();} else {return 0;}}@Overridepublic Object getChild(int groupPosition, int childPosition) {return data.get(groupPosition).getGoods().get(childPosition);}@Overridepublic long getChildId(int groupPosition, int childPosition) {return childPosition;}@Overridepublic View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {ChildViewHolder childViewHolder;if (convertView == null) {convertView = View.inflate(context, R.layout.item_shopping_car_child, null);childViewHolder = new ChildViewHolder(convertView);convertView.setTag(childViewHolder);} else {childViewHolder = (ChildViewHolder) convertView.getTag();}final ShoppingCarDataBean.DatasBean datasBean = data.get(groupPosition);//店铺IDString store_id = datasBean.getStore_id();//店铺名称String store_name = datasBean.getStore_name();//店铺是否在购物车中被选中final boolean isSelect_shop = datasBean.getIsSelect_shop();final ShoppingCarDataBean.DatasBean.GoodsBean goodsBean = datasBean.getGoods().get(childPosition);//商品图片String goods_image = goodsBean.getGoods_image();//商品IDfinal String goods_id = goodsBean.getGoods_id();//商品名称String goods_name = goodsBean.getGoods_name();//商品价格String goods_price = goodsBean.getGoods_price();//商品数量String goods_num = goodsBean.getGoods_num();//商品是否被选中final boolean isSelect = goodsBean.getIsSelect();Glide.with(context).load(R.drawable.img).into(childViewHolder.ivPhoto);if (goods_name != null) {childViewHolder.tvName.setText(goods_name);} else {childViewHolder.tvName.setText("");}if (goods_price != null) {childViewHolder.tvPriceValue.setText(goods_price);} else {childViewHolder.tvPriceValue.setText("");}if (goods_num != null) {childViewHolder.tvEditBuyNumber.setText(goods_num);} else {childViewHolder.tvEditBuyNumber.setText("");}//商品是否被选中if (isSelect) {childViewHolder.ivSelect.setImageResource(R.drawable.xuanze_xuanzhong);} else {childViewHolder.ivSelect.setImageResource(R.drawable.unselect);}//商品选择框的点击事件childViewHolder.ivSelect.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {goodsBean.setIsSelect(!isSelect);if (!isSelect == false) {datasBean.setIsSelect_shop(false);}notifyDataSetChanged();}});//加号的点击事件childViewHolder.ivEditAdd.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//模拟加号操作String num = goodsBean.getGoods_num();Integer integer = Integer.valueOf(num);integer++;goodsBean.setGoods_num(integer + "");notifyDataSetChanged();/*** 实际开发中,通过回调请求后台接口实现数量的加减*/if (mChangeCountListener != null) {mChangeCountListener.onChangeCount(goods_id);}}});//减号的点击事件childViewHolder.ivEditSubtract.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//模拟减号操作String num = goodsBean.getGoods_num();Integer integer = Integer.valueOf(num);if (integer > 1) {integer--;goodsBean.setGoods_num(integer + "");/*** 实际开发中,通过回调请求后台接口实现数量的加减*/if (mChangeCountListener != null) {mChangeCountListener.onChangeCount(goods_id);}} else {ToastUtil.makeText(context, "商品不能再减少了");}notifyDataSetChanged();}});if (childPosition == data.get(groupPosition).getGoods().size() - 1) {childViewHolder.view.setVisibility(View.GONE);childViewHolder.viewLast.setVisibility(View.VISIBLE);} else {childViewHolder.view.setVisibility(View.VISIBLE);childViewHolder.viewLast.setVisibility(View.GONE);}return convertView;}static class ChildViewHolder {@InjectView(R.id.iv_select)ImageView ivSelect;@InjectView(R.id.iv_photo)ImageView ivPhoto;@InjectView(R.id.tv_name)TextView tvName;@InjectView(R.id.tv_price_key)TextView tvPriceKey;@InjectView(R.id.tv_price_value)TextView tvPriceValue;@InjectView(R.id.iv_edit_subtract)ImageView ivEditSubtract;@InjectView(R.id.tv_edit_buy_number)TextView tvEditBuyNumber;@InjectView(R.id.iv_edit_add)ImageView ivEditAdd;@InjectView(R.id.view)View view;@InjectView(R.id.view_last)View viewLast;ChildViewHolder(View view) {ButterKnife.inject(this, view);}}//-----------------------------------------------------------------------------------------------@Overridepublic boolean isChildSelectable(int groupPosition, int childPosition) {return false;}@Overridepublic boolean hasStableIds() {return false;}//删除的回调public interface OnDeleteListener {void onDelete();}public void setOnDeleteListener(OnDeleteListener listener) {mDeleteListener = listener;}private OnDeleteListener mDeleteListener;//修改商品数量的回调public interface OnChangeCountListener {void onChangeCount(String goods_id);}public void setOnChangeCountListener(OnChangeCountListener listener) {mChangeCountListener = listener;}private OnChangeCountListener mChangeCountListener;}
4、购物车数据的bean类(ShoppingCarDataBean.class)
/*** 购物车数据的bean类*/public class ShoppingCarDataBean {private int code;private List<DatasBean> datas;public int getCode() {return code;}public void setCode(int code) {this.code = code;}public List<DatasBean> getDatas() {return datas;}public void setDatas(List<DatasBean> datas) {this.datas = datas;}public static class DatasBean {private String store_id;private String store_name;private boolean isSelect_shop; //店铺是否在购物车中被选中private List<GoodsBean> goods;public boolean getIsSelect_shop() {return isSelect_shop;}public void setIsSelect_shop(boolean select_shop) {isSelect_shop = select_shop;}public String getStore_id() {return store_id;}public void setStore_id(String store_id) {this.store_id = store_id;}public String getStore_name() {return store_name;}public void setStore_name(String store_name) {this.store_name = store_name;}public List<GoodsBean> getGoods() {return goods;}public void setGoods(List<GoodsBean> goods) {this.goods = goods;}public static class GoodsBean {private String goods_id;private String goods_image;private String goods_name;private String goods_num;private String goods_price;private boolean isSelect; //商品是否在购物车中被选中public boolean getIsSelect() {return isSelect;}public void setIsSelect(boolean isSelect) {this.isSelect = isSelect;}public String getGoods_id() {return goods_id;}public void setGoods_id(String goods_id) {this.goods_id = goods_id;}public String getGoods_image() {return goods_image;}public void setGoods_image(String goods_image) {this.goods_image = goods_image;}public String getGoods_name() {return goods_name;}public void setGoods_name(String goods_name) {this.goods_name = goods_name;}public String getGoods_num() {return goods_num;}public void setGoods_num(String goods_num) {this.goods_num = goods_num;}public String getGoods_price() {return goods_price;}public void setGoods_price(String goods_price) {this.goods_price = goods_price;}}}}
5、分店铺实现布局
效果图(红色部分):

<?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="match_parent"android:background="#ffffff"android:orientation="vertical"><LinearLayoutandroid:id="@+id/ll"android:layout_width="match_parent"android:layout_height="40dp"android:orientation="horizontal"><ImageViewandroid:id="@+id/iv_select"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_marginLeft="10dp"android:background="@drawable/unselect" /><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_marginLeft="10dp"android:background="@drawable/biaoqianlan_kefu" /><TextViewandroid:id="@+id/tv_store_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginLeft="10dp"android:text="店铺名称"android:textColor="#333333"android:textSize="14dp"android:maxLines="1"android:ellipsize="end"/></LinearLayout><Viewandroid:layout_width="match_parent"android:layout_height="0.5dp"android:layout_marginLeft="10dp"android:background="#cccccc" /></LinearLayout>
6、购物车中商品Item布局文件
效果图:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#ffffff"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="100dp"android:background="#ffffff"><ImageViewandroid:id="@+id/iv_select"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_gravity="center_vertical"android:padding="10dp"android:src="@drawable/unselect" /><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:id="@+id/iv_photo"android:layout_width="90dp"android:layout_height="90dp"android:layout_centerVertical="true"android:background="#ededed"android:scaleType="centerCrop" /><TextViewandroid:id="@+id/tv_name"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:layout_marginTop="10dp"android:layout_toRightOf="@id/iv_photo"android:ellipsize="end"android:maxLines="2"android:text="时空房间啊链接法兰克福骄傲拉开飞机阿里进来撒劫匪了卡减肥了看见拉杀劫匪垃圾费垃圾费啦"android:textColor="#333333"android:textSize="14dp" /><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="35dp"android:layout_alignParentBottom="true"android:layout_marginLeft="10dp"android:layout_toRightOf="@id/iv_photo"><TextViewandroid:id="@+id/tv_price_key"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:text="¥"android:textColor="#ee1d23"android:textSize="12dp" /><TextViewandroid:id="@+id/tv_price_value"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_marginLeft="2dp"android:layout_toRightOf="@id/tv_price_key"android:text="499"android:textColor="#ee1d23"android:textSize="14dp" /><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="match_parent"android:layout_alignParentRight="true"android:layout_centerVertical="true"android:gravity="center"android:orientation="horizontal"><ImageViewandroid:id="@+id/iv_edit_subtract"android:layout_width="wrap_content"android:layout_height="match_parent"android:paddingLeft="15dp"android:paddingRight="15dp"android:src="@drawable/iv_edit_subtract" /><TextViewandroid:id="@+id/tv_edit_buy_number"android:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center"android:minEms="1"android:text="1"android:textColor="#666666"android:textSize="12dp" /><ImageViewandroid:id="@+id/iv_edit_add"android:layout_width="wrap_content"android:layout_height="match_parent"android:paddingLeft="15dp"android:paddingRight="15dp"android:src="@drawable/iv_edit_add" /></LinearLayout><Viewandroid:id="@+id/view"android:layout_width="match_parent"android:layout_height="0.5dp"android:layout_alignParentBottom="true"android:background="#cccccc" /></RelativeLayout></RelativeLayout></LinearLayout><Viewandroid:id="@+id/view_last"android:layout_width="match_parent"android:layout_height="10dp"android:layout_alignParentBottom="true"android:background="#ededed"android:visibility="gone" /></LinearLayout>
自此,购物车的功能基本已经实现啦。
需要源码的童鞋在【龙旋】公众号对话框输入关键字【购物车功能】即可获取。
评论
