Android實現(xiàn)商城購物車功能
最近公司項目做商城模塊,需要實現(xiàn)購物車功能,主要實現(xiàn)了單選、全選,金額合計,商品刪除,商品數(shù)量加減等功能,先看看效果圖:

一、實現(xiàn)步驟:
0、添加依賴庫
1、購物車主界面布局文件(activity_main.xml)
2、購物車實現(xiàn)邏輯主界面(MainActivity.class)
3、使用ExpandableListView,繼承BaseExpandableListAdapter
4、購物車數(shù)據(jù)的bean類(ShoppingCarDataBean.class)
5、分店鋪實現(xiàn)布局
6、購物車中商品Item布局文件
二、實現(xiàn)過程:
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="結(jié)算"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、購物車實現(xiàn)邏輯主界面(MainActivity.class)
/*** 購物車實現(xiàn)* 主要功能:* 1.單選、全選;* 2.合計;* 3.刪除;* 4.商品數(shù)量加減;*/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;//模擬的購物車數(shù)據(jù)(實際開發(fā)中使用后臺返回的數(shù)據(jù))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://刷新數(shù)據(jù)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;}}/*** 初始化數(shù)據(jù)*/private void initData() {//使用Gson解析購物車數(shù)據(jù),//ShoppingCarDataBean為bean類,Gson按照bean類的格式解析數(shù)據(jù)/*** 實際開發(fā)中,通過請求后臺接口獲取購物車數(shù)據(jù)并解析*/Gson gson = new Gson();ShoppingCarDataBean shoppingCarDataBean = gson.fromJson(shoppingCarData, ShoppingCarDataBean.class);datas = shoppingCarDataBean.getDatas();initExpandableListViewData(datas);}/*** 初始化ExpandableListView* 創(chuàng)建數(shù)據(jù)適配器adapter,并進行初始化操作*/private void initExpandableListView() {shoppingCarAdapter = new ShoppingCarAdapter(context, llSelectAll, ivSelectAll, btnOrder, btnDelete, rlTotalPrice, tvTotalPrice);elvShoppingCar.setAdapter(shoppingCarAdapter);//刪除的回調(diào)shoppingCarAdapter.setOnDeleteListener(new ShoppingCarAdapter.OnDeleteListener() {@Overridepublic void onDelete() {initDelete();/*** 實際開發(fā)中,在此請求刪除接口,刪除成功后,* 通過initExpandableListViewData()方法刷新購物車數(shù)據(jù)。* 注:通過bean類中的DatasBean的isSelect_shop屬性,判斷店鋪是否被選中;* GoodsBean的isSelect屬性,判斷商品是否被選中,* (true為選中,false為未選中)*/}});//修改商品數(shù)量的回調(diào)shoppingCarAdapter.setOnChangeCountListener(new ShoppingCarAdapter.OnChangeCountListener() {@Overridepublic void onChangeCount(String goods_id) {/*** 實際開發(fā)中,在此請求修改商品數(shù)量的接口,商品數(shù)量修改成功后,* 通過initExpandableListViewData()方法刷新購物車數(shù)據(jù)。*/}});}/*** 初始化ExpandableListView的數(shù)據(jù)* 并在數(shù)據(jù)刷新時,頁面保持當(dāng)前位置** @param datas 購物車的數(shù)據(jù)*/private void initExpandableListViewData(List<ShoppingCarDataBean.DatasBean> datas) {if (datas != null && datas.size() > 0) {//刷新數(shù)據(jù)時,保持當(dāng)前位置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為有,則需要刷新數(shù)據(jù);反之,則不需要;boolean hasSelect = false;//創(chuàng)建臨時的List,用于存儲沒有被選中的購物車數(shù)據(jù)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;//跳出本次循環(huán),繼續(xù)下次循環(huán)。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);// 設(shè)置點擊屏幕Dialog不消失roundCornerDialog.setOnKeyListener(keylistener);//設(shè)置點擊返回鍵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;}/*** 自定義設(shè)置數(shù)據(jù)方法;* 通過notifyDataSetChanged()刷新數(shù)據(jù),可保持當(dāng)前位置** @param data 需要刷新的數(shù)據(jù)*/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("");}//店鋪內(nèi)的商品都選中的時候,店鋪的也要選中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,所以這一塊代碼要放到一起執(zhí)行//店鋪是否在購物車中被選中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();}});//當(dāng)所有的選擇框都是選中的時候,全選也要選中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;//根據(jù)標(biāo)記,跳出嵌套循環(huán)}}}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類型完整顯示,不用科學(xué)計數(shù)法顯示大寫字母EDecimalFormat decimalFormat = new DecimalFormat("0.00");tvTotalPrice.setText("¥" + decimalFormat.format(total_price));}}}//去結(jié)算的點擊事件btnOrder.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//創(chuàng)建臨時的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) {//如果有被選中的/*** 實際開發(fā)中,如果有被選中的商品,* 則跳轉(zhuǎn)到確認(rèn)訂單頁面,完成后續(xù)訂單流程。*/ToastUtil.makeText(context, "跳轉(zhuǎn)到確認(rèn)訂單頁面,完成后續(xù)訂單流程");} else {ToastUtil.makeText(context, "請選擇要購買的商品");}}});//刪除的點擊事件btnDelete.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {/*** 實際開發(fā)中,通過回調(diào)請求后臺接口實現(xiàn)刪除操作*/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();//商品數(shù)量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();/*** 實際開發(fā)中,通過回調(diào)請求后臺接口實現(xiàn)數(shù)量的加減*/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 + "");/*** 實際開發(fā)中,通過回調(diào)請求后臺接口實現(xiàn)數(shù)量的加減*/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;}//刪除的回調(diào)public interface OnDeleteListener {void onDelete();}public void setOnDeleteListener(OnDeleteListener listener) {mDeleteListener = listener;}private OnDeleteListener mDeleteListener;//修改商品數(shù)量的回調(diào)public interface OnChangeCountListener {void onChangeCount(String goods_id);}public void setOnChangeCountListener(OnChangeCountListener listener) {mChangeCountListener = listener;}private OnChangeCountListener mChangeCountListener;}
4、購物車數(shù)據(jù)的bean類(ShoppingCarDataBean.class)
/*** 購物車數(shù)據(jù)的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、分店鋪實現(xiàn)布局
效果圖(紅色部分):

<?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>
自此,購物車的功能基本已經(jīng)實現(xiàn)啦。
需要源碼的童鞋在【龍旋】公眾號對話框輸入關(guān)鍵字【購物車功能】即可獲取。
評論
圖片
表情
