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">
 <LinearLayout
 android:id="@+id/ll_gouwuche"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="#ededed"
 android:orientation="vertical">
 <RelativeLayout
  android:layout_width="match_parent"
  android:layout_height="48dp"
  android:background="#ffffff"
  android:orientation="vertical">
  <ImageView
  android: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" />
  <TextView
  android: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" />
  <TextView
  android: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" />
  <View
  android:layout_width="match_parent"
  android:layout_height="0.5dp"
  android:layout_alignParentBottom="true"
  android:background="#cccccc" />
 </RelativeLayout>
 <ExpandableListView
  android: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" />
 <RelativeLayout
  android:id="@+id/rl"
  android:layout_width="match_parent"
  android:layout_height="54dp"
  android:background="#ffffff"
  android:visibility="gone">
  <LinearLayout
  android:id="@+id/ll_select_all"
  android:layout_width="wrap_content"
  android:layout_height="match_parent"
  android:orientation="horizontal"
  android:paddingRight="10dp">
  <ImageView
   android: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" />
  <TextView
   android: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>
  <Button
  android: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" />
  <Button
  android: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" />
  <RelativeLayout
  android: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">
  <TextView
   android: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" />
  <TextView
   android: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>
  <View
  android:layout_width="match_parent"
  android:layout_height="0.5dp"
  android:background="#cccccc" />
 </RelativeLayout>
 </LinearLayout>
 <RelativeLayout
 android:id="@+id/rl_no_contant"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_centerInParent="true"
 android:visibility="gone">
 <ImageView
  android: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" />
 <TextView
  android: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)

package com.showly.yglin.shoppingcar;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.google.gson.Gson;
import com.showly.yglin.shoppingcar.adapter.ShoppingCarAdapter;
import com.showly.yglin.shoppingcar.bean.ShoppingCarDataBean;
import com.showly.yglin.shoppingcar.customview.RoundCornerDialog;
import com.showly.yglin.shoppingcar.util.ToastUtil;
import java.util.ArrayList;
import java.util.List;
import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;
/**
 * 购物车实现
 * 主要功能:
 *  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;
 @Override
 protected 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() {
  @Override
  public void onDelete() {
  initDelete();
  /**
   * 实际开发中,在此请求删除接口,删除成功后,
   * 通过initExpandableListViewData()方法刷新购物车数据。
   * 注:通过bean类中的DatasBean的isSelect_shop属性,判断店铺是否被选中;
   *   GoodsBean的isSelect属性,判断商品是否被选中,
   *   (true为选中,false为未选中)
   */
  }
 });
 //修改商品数量的回调
 shoppingCarAdapter.setOnChangeCountListener(new ShoppingCarAdapter.OnChangeCountListener() {
  @Override
  public 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() {
  @Override
  public 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() {
  @Override
  public void onClick(View v) {
  roundCornerDialog.dismiss();
  datas = datasTemp;
  initExpandableListViewData(datas);
  }
 });
 //取消
 tv_logout_cancel.setOnClickListener(new View.OnClickListener() {
  @Override
  public 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

package com.showly.yglin.shoppingcar.adapter;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.showly.yglin.shoppingcar.R;
import com.showly.yglin.shoppingcar.bean.ShoppingCarDataBean;
import com.showly.yglin.shoppingcar.util.ToastUtil;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import butterknife.ButterKnife;
import butterknife.InjectView;
/**
 * 购物车的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();
 }
 @Override
 public int getGroupCount() {
 if (data != null && data.size() > 0) {
  return data.size();
 } else {
  return 0;
 }
 }
 @Override
 public Object getGroup(int groupPosition) {
 return data.get(groupPosition);
 }
 @Override
 public long getGroupId(int groupPosition) {
 return groupPosition;
 }
 @Override
 public 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);
 //店铺ID
 String 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() {
  @Override
  public 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() {
  @Override
  public 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类型完整显示,不用科学计数法显示大写字母E
   DecimalFormat decimalFormat = new DecimalFormat("0.00");
   tvTotalPrice.setText("¥" + decimalFormat.format(total_price));
  }
  }
 }
 //去结算的点击事件
 btnOrder.setOnClickListener(new View.OnClickListener() {
  @Override
  public 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() {
  @Override
  public 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);
 }
 }
 //------------------------------------------------------------------------------------------------
 @Override
 public 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;
 }
 }
 @Override
 public Object getChild(int groupPosition, int childPosition) {
 return data.get(groupPosition).getGoods().get(childPosition);
 }
 @Override
 public long getChildId(int groupPosition, int childPosition) {
 return childPosition;
 }
 @Override
 public 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);
 //店铺ID
 String 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();
 //商品ID
 final 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() {
  @Override
  public void onClick(View v) {
  goodsBean.setIsSelect(!isSelect);
  if (!isSelect == false) {
   datasBean.setIsSelect_shop(false);
  }
  notifyDataSetChanged();
  }
 });
 //加号的点击事件
 childViewHolder.ivEditAdd.setOnClickListener(new View.OnClickListener() {
  @Override
  public 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() {
  @Override
  public 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);
 }
 }
 //-----------------------------------------------------------------------------------------------
 @Override
 public boolean isChildSelectable(int groupPosition, int childPosition) {
 return false;
 }
 @Override
 public 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)
package com.showly.yglin.shoppingcar.bean;
import java.util.List;
/**
 * 购物车数据的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">
 <LinearLayout
 android:id="@+id/ll"
 android:layout_width="match_parent"
 android:layout_height="40dp"
 android:orientation="horizontal">
 <ImageView
  android: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" />
 <ImageView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center_vertical"
  android:layout_marginLeft="10dp"
  android:background="@drawable/biaoqianlan_kefu" />
 <TextView
  android: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>
 <View
 android:layout_width="match_parent"
 android:layout_height="0.5dp"
 android:layout_marginLeft="10dp"
 android:background="#cccccc" />
</LinearLayout>

6.购物车中商品Item布局文件

效果图:

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<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">
 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="100dp"
 android:background="#ffffff">
 <ImageView
  android: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" />
 <RelativeLayout
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <ImageView
  android:id="@+id/iv_photo"
  android:layout_width="90dp"
  android:layout_height="90dp"
  android:layout_centerVertical="true"
  android:background="#ededed"
  android:scaleType="centerCrop" />
  <TextView
  android: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" />
  <RelativeLayout
  android:layout_width="match_parent"
  android:layout_height="35dp"
  android:layout_alignParentBottom="true"
  android:layout_marginLeft="10dp"
  android:layout_toRightOf="@id/iv_photo">
  <TextView
   android: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" />
  <TextView
   android: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" />
  <LinearLayout
   android:layout_width="wrap_content"
   android:layout_height="match_parent"
   android:layout_alignParentRight="true"
   android:layout_centerVertical="true"
   android:gravity="center"
   android:orientation="horizontal">
   <ImageView
   android: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" />
   <TextView
   android: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" />
   <ImageView
   android: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>
  <View
   android:id="@+id/view"
   android:layout_width="match_parent"
   android:layout_height="0.5dp"
   android:layout_alignParentBottom="true"
   android:background="#cccccc" />
  </RelativeLayout>
 </RelativeLayout>
 </LinearLayout>
 <View
 android:id="@+id/view_last"
 android:layout_width="match_parent"
 android:layout_height="10dp"
 android:layout_alignParentBottom="true"
 android:background="#ededed"
 android:visibility="gone" />
</LinearLayout>

自此,购物车的功能基本已经实现了

总结

以上所述是小编给大家介绍的Android实现商城购物车功能的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • Android实现购物车添加物品的动画效果

    前言:当我们写商城类的项目的时候,一般都会有加入购物车的功能,加入购物车的时候会有一些抛物线动画,最近做到这个功能,借助别人的demo写了一个. 效果: 开发环境:AndroidStudio2.1.2+gradle-2.10 涉及知识:1.沉浸式状态栏,2.单位精度计算(价格),3.List之Iterator. 部分代码: public class MainActivity extends AppCompatActivity implements FoodAdapter.FoodActionCa

  • Android实现购物车及其他功能的角标

    1.先来张效果图 2.自定义一个角标工具类BottomBarView . ** * Created by Administrator on 2016/12/27. * 角标工具类 */ public class BottomBarView extends RelativeLayout { private Context context; private TextView bar_num; private int count = 0; public BottomBarView(Context co

  • Android实现仿淘宝购物车增加和减少商品数量功能demo示例

    本文实例讲述了Android实现仿淘宝购物车增加和减少商品数量功能.分享给大家供大家参考,具体如下: 在前面一篇<Android实现的仿淘宝购物车demo示例>中,小编简单的介绍了如何使用listview来实现购物车,但是仅仅是简单的实现了列表的功能,随之而来一个新的问题,买商品的时候,我们可能不止想买一件商品,想买多个,或许有因为某种原因点错了,本来想买一件来着,小手不小心抖了一下,把数量错点成了三个,这个时候就涉及到一个新的功能,那就是增加和减少商品的数量,今天这篇博文,小编就来和小伙伴们

  • Android实现的仿淘宝购物车demo示例

    本文实例讲述了Android实现的仿淘宝购物车.分享给大家供大家参考,具体如下: 夏的热情渐渐退去,秋如期而至,丰收的季节,小编继续着实习之路,走着走着,就走到了购物车,逛过淘宝或者是京东的小伙伴都知道购物车里面的宝贝可不止一件,对于爱购物的姑娘来说,购物车里面的商品恐怕是爆满,添加不进去了,以前逛淘宝的时候,小编没有想过要怎么样实现购物车,就知道在哪儿一个劲儿的逛,但是现在不一样了,小编做为一个开发者,想的就是该如何实现,捣鼓了两天的时间,用listview来实现,已经有模有样了,现在小编就来

  • Android实现购物车功能

    最近看了一些淘宝购物车的demo,于是也写了一个. 效果图如下: 主要代码如下: actvity中的代码: public class ShoppingCartActivity extends BaseActivity { private List<Test> data; private ListView mListView; private ShoppingCartAdapter adapter; private RelativeLayout rlRefresh; private TextVi

  • Android仿硅谷商城实现购物车实例代码

    本文实例为大家分享了Android实现购物车的具体代码,供大家参考,具体内容如下 1_设置点击事件和定义状态 在GovaffairPager类中 public class GovaffairPager extends BasePager { ............ /** * 编辑状态 */ private static final int ACTION_EDIT = 0; /** * 完成状态 */ private static final int ACTION_COMPLETE = 1;

  • Android制作简单的普通购物车

    本文实例为大家分享了Android普通购物车制作过程,供大家参考,具体内容如下 1.最新项目新增了类似购物车功能,如下图所示: 当时刚看到此页面的时候,第一反应是利用 ListView嵌套Listview,经过一番操作最终也实现了此功能.当时也没有考虑性能问题,只考虑能写出来.后来嵌套数据,当数据量较大时,滑动Listview可以明显感觉到卡顿,这对用户来说是很难忍受的,所以才有了找到替代方案的想法,看到网上主流的是用ExpandableListView来实现此功能,所以我也用此方案来写一下.

  • Android把商品添加到购物车的动画效果(贝塞尔曲线)

    当我们写商城类的项目的时候,一般都会有加入购物车的功能,加入购物车的时候会有一些抛物线动画,具体代码如下: 实现效果如图: 思路: 确定动画的起终点 在起终点之间使用二次贝塞尔曲线填充起终点之间的点的轨迹 设置属性动画,ValueAnimator插值器,获取中间点的坐标 将执行动画的控件的x.y坐标设为上面得到的中间点坐标 开启属性动画 当动画结束时的操作 难点: PathMeasure的使用 - getLength() - boolean getPosTan(float distance, f

  • Android实现添加商品到购物车动画效果

    本文实例为大家分享了Android添加商品到购物车的具体代码,供大家参考,具体内容如下 实现需求 在商品列表页面中,从列表item添加商品时,实现一个动画,给人感觉像是在添加商品到购物车. 思路 1.获取各个动画执行对象的起点和终点的坐标,利用PathMeasure绘制绘制贝塞尔曲线: 2.为商品图片设置属性动画: 3.为动画设置addUpdateListene监听器,更新view的坐标. 效果图: MainActivity.java package com.zlw.yzm.demo; impo

  • Android仿外卖购物车功能

    先看看效果图: 知识点分析 效果图来看不复杂内容并没多少,值得介绍一下的知识点也就下面几个吧 - 列表标题悬停 - 左右列表滑动时联动 - 添加商品时的抛物线动画 - 底部弹出购物车清单 - 数据的同步 另外就是实现效果的时候可能会遇到的几个坑... 布局很简单直接进入代码 1:列表标题悬停 现在做项目列表什么的基本抛弃了ListView改用RecyclerView,上篇博客中的标题悬停也是使用了一个RecyclerView的开源项目sticky-headers-recyclerview,不过写

  • Android实现简单购物车功能

    本文实例为大家分享了Android实现购物车功能的具体代码,供大家参考,具体内容如下 MainActivity布局: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"

随机推荐