購物車簡單實現(二級列表ExpandableListView)
阿新 • • 發佈:2018-12-27
MVP請求資料自行解決
MainActivity
package com.zjh.administrat.shopping_cartdemo.view; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.ExpandableListView; import android.widget.TextView; import com.zjh.administrat.shopping_cartdemo.R; import com.zjh.administrat.shopping_cartdemo.adapter.MyAdapter; import com.zjh.administrat.shopping_cartdemo.bean.ShoppingBean; import com.zjh.administrat.shopping_cartdemo.presenter.IPresenterImpl; import java.util.HashMap; import java.util.Map; public class MainActivity extends AppCompatActivity implements IView { private String urlStr = "http://www.zhaoapi.cn/product/getCarts"; private IPresenterImpl iPresenter; private ExpandableListView el_cart; private CheckBox cb_cart_all_select; private TextView tv_cart_total_price; private Button btn_cart_pay; private MyAdapter adapter; private ShoppingBean data; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); adapter = new MyAdapter(this); el_cart.setAdapter(adapter); } //初始化view private void initData() { iPresenter = new IPresenterImpl(this); Map<String, String> map = new HashMap<>(); map.put("uid", "71"); iPresenter.pRequestData(urlStr, map, ShoppingBean.class); } //B.重新整理checkbox狀態和總價和總數量 private void refreshSelectedAndTotalPriceAndTotalNumber() { //去判斷是否所有得商品都被選中 boolean allProductsSelected = adapter.isAllProductsSelected(); //設定給全選 cb_cart_all_select.setChecked(allProductsSelected); //計算總價 float totalPrice = adapter.calculateTotalPrice(); tv_cart_total_price.setText("總價:¥"+totalPrice); //計算總數量 int totalNumber = adapter.calculateTotalNumber(); btn_cart_pay.setText("去結算("+totalNumber+")"); } //初始化的操作 private void initView() { el_cart = findViewById(R.id.el_cart); cb_cart_all_select = findViewById(R.id.cb_cart_all_select); tv_cart_total_price = findViewById(R.id.tv_cart_total_price); btn_cart_pay = findViewById(R.id.btn_cart_pay); //全選按鈕 findViewById(R.id.cb_cart_all_select).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //底部全選按鈕選中的時候所有得商品都被選中 boolean allProductsSelected = adapter.isAllProductsSelected(); adapter.changeAllProductStatus(!allProductsSelected); adapter.notifyDataSetChanged(); //重新整理底部資料 refreshSelectedAndTotalPriceAndTotalNumber(); } }); } //獲取資料 @Override public void viewData(Object object) { data = (ShoppingBean) object; adapter.setDatas(data.getData()); for (int p = 0; p < data.getData().size(); p++) { el_cart.expandGroup(p); } //回撥方法 adapter.setOnCartListChangeListener(new MyAdapter.OnCartListChangeListener() { @Override public void onSellerCheckedChange(int i) { //商家被點選 boolean currentSellerAllProductSelected = adapter.isCurrentSellerAllProductSelected(i); adapter.changeCurrentSellerAllProductsStatus(i, !currentSellerAllProductSelected); adapter.notifyDataSetChanged(); //B.重新整理底部資料 refreshSelectedAndTotalPriceAndTotalNumber(); } @Override public void onProductCheckedChange(int i, int i1) { //點選商品得複選框 adapter.changeCurrentProductStatus(i, i1); adapter.notifyDataSetChanged(); //B.重新整理底部資料 refreshSelectedAndTotalPriceAndTotalNumber(); } @Override public void onProducNumberChange(int i, int i1, int number) { //當加減被點選 adapter.changeCurrentProductNumber(i, i1, number); adapter.notifyDataSetChanged(); //B.重新整理底部資料 refreshSelectedAndTotalPriceAndTotalNumber(); } }); } @Override protected void onDestroy() { super.onDestroy(); iPresenter.onDetch(); } }
AddSubView自定(商品數量)
package com.zjh.administrat.shopping_cartdemo.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import com.zjh.administrat.shopping_cartdemo.R; public class AddSubView extends LinearLayout implements View.OnClickListener { private int number = 1; private TextView sub_tv, product_number_tv, add_tv; public AddSubView(Context context) { this(context,null); } public AddSubView(Context context, AttributeSet attrs) { this(context, attrs,0); } public AddSubView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); View view = inflate(context, R.layout.add_remove, this); sub_tv = view.findViewById(R.id.sub_tv); product_number_tv = view.findViewById(R.id.product_number_tv); add_tv = view.findViewById(R.id.add_tv); sub_tv.setOnClickListener(this); add_tv.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.sub_tv: if (number > 1) { --number; product_number_tv.setText(number+""); if (mNumberChangeListener != null) { mNumberChangeListener.onNumberChange(number); } } else { Toast.makeText(getContext(), "我是有底線的", Toast.LENGTH_SHORT).show(); } break; case R.id.add_tv: if (number < 9) { ++number; product_number_tv.setText(number+""); if (mNumberChangeListener != null) { mNumberChangeListener.onNumberChange(number); } } else { Toast.makeText(getContext(), "每人限購10件", Toast.LENGTH_SHORT).show(); } break; default: break; } } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; product_number_tv.setText(number+""); } //成員變數 OnNumberChangeListener mNumberChangeListener; public void setOnNumberChangeListener(OnNumberChangeListener onNumberChangeListener) { this.mNumberChangeListener = onNumberChangeListener; } public interface OnNumberChangeListener { void onNumberChange(int number); } }
MyAdapter介面卡
package com.zjh.administrat.shopping_cartdemo.adapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; import com.zjh.administrat.shopping_cartdemo.R; import com.zjh.administrat.shopping_cartdemo.bean.ShoppingBean; import com.zjh.administrat.shopping_cartdemo.view.AddSubView; import java.util.ArrayList; import java.util.List; public class MyAdapter extends BaseExpandableListAdapter { private List<ShoppingBean.DataBean> list; private Context mContext; public MyAdapter(Context context) { mContext = context; list = new ArrayList<>(); } public void setDatas(List<ShoppingBean.DataBean> data) { if (data != null){ list.addAll(data); } notifyDataSetChanged(); } @Override public int getGroupCount() { return list.size(); } @Override public int getChildrenCount(int groupPosition) { return list.get(groupPosition).getList().size(); } @Override public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { ShoppingBean.DataBean dataBean = list.get(groupPosition); ParentViewHolder parentViewHolder; if (convertView == null) { convertView = LayoutInflater.from(mContext).inflate(R.layout.item_cart_parent, parent, false); parentViewHolder = new ParentViewHolder(convertView); convertView.setTag(parentViewHolder); } else { parentViewHolder = (ParentViewHolder) convertView.getTag(); } parentViewHolder.seller_name_tv.setText(dataBean.getSellerName()); boolean currentSellerAllProductSelected = isCurrentSellerAllProductSelected(groupPosition); parentViewHolder.seller_cb.setChecked(currentSellerAllProductSelected); //D.設定點選CheckBox parentViewHolder.seller_cb.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mOnCartListChangeListener != null) { mOnCartListChangeListener.onSellerCheckedChange(groupPosition); } } }); return convertView; } @Override public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ChildViewHolder childViewHolder; if (convertView == null) { convertView = LayoutInflater.from(mContext).inflate(R.layout.item_cart_child, parent, false); childViewHolder = new ChildViewHolder(convertView); convertView.setTag(childViewHolder); } else { childViewHolder = (ChildViewHolder) convertView.getTag(); } //設定商品名字 childViewHolder.product_title_name_tv.setText(list.get(groupPosition).getList().get(childPosition).getTitle()); //設定商品單價 childViewHolder.product_price_tv.setText("¥:"+list.get(groupPosition).getList().get(childPosition).getPrice()+""); //設定複選框是否選中 childViewHolder.child_cb.setChecked(list.get(groupPosition).getList().get(childPosition).getSelected() == 1); //設定組合式自定義控制元件內部的數量 childViewHolder.add_remove_view.setNumber(list.get(groupPosition).getList().get(childPosition).getNum()); String str = ""; int length = list.get(groupPosition).getList().get(childPosition).getImages().length(); for (int j = 0; j < length; j++) { if (list.get(groupPosition).getList().get(childPosition).getImages().substring(j, j + 1).equals("|")) { str = list.get(groupPosition).getList().get(childPosition).getImages().substring(j + 1, length).trim(); } } Glide.with(mContext).load(str).into(childViewHolder.product_icon_iv); //D.設定商品CheckBox的點選事件,通過介面回撥,暴露給外面 childViewHolder.child_cb.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mOnCartListChangeListener != null) { mOnCartListChangeListener.onProductCheckedChange(groupPosition, childPosition); } } }); //D.設定商品數量的點選事件,通過介面回撥,暴露給外面 childViewHolder.add_remove_view.setOnNumberChangeListener(new AddSubView.OnNumberChangeListener() { @Override public void onNumberChange(int number) { if (mOnCartListChangeListener != null){ mOnCartListChangeListener.onProducNumberChange(groupPosition, childPosition, number); } } }); return convertView; } public boolean isCurrentSellerAllProductSelected (int i){ //根據商品改變商家--如果商品全部選中商家則選中--有一個商品沒選中則商家不選中 ShoppingBean.DataBean dataBean = list.get(i); List<ShoppingBean.DataBean.ListBean> beans = dataBean.getList(); for (ShoppingBean.DataBean.ListBean bean : beans) { if (bean.getSelected() == 0) { return false; } } return true; } public boolean isAllProductsSelected () { //根據商品改變全選--如果商品全部選中全選則選中--有一個商品沒選中則全選不選中 for (int x = 0; x < list.size(); x++) { ShoppingBean.DataBean dataBean = list.get(x); List<ShoppingBean.DataBean.ListBean> list1 = dataBean.getList(); for (int j = 0; j < list1.size(); j++) { if (list1.get(j).getSelected() == 0) { return false; } } } return true; } public int calculateTotalNumber () { //計算總數量 int totalNumber = 0; for (int i = 0; i < list.size(); i++) { ShoppingBean.DataBean dataBean = list.get(i); List<ShoppingBean.DataBean.ListBean> list1 = dataBean.getList(); for (int j = 0; j < list1.size(); j++) { if (list1.get(j).getSelected() == 1) { int num = list1.get(j).getNum(); totalNumber += num; } } } return totalNumber; } public float calculateTotalPrice () { //獲取總價 float totalPrice = 0; for (int i = 0; i < list.size(); i++) { ShoppingBean.DataBean dataBean = list.get(i); List<ShoppingBean.DataBean.ListBean> list1 = dataBean.getList(); for (int j = 0; j < list1.size(); j++) { if (list1.get(j).getSelected() == 1) { float price = (float) list1.get(j).getPrice(); int num = list1.get(j).getNum(); totalPrice += price * num; } } } return totalPrice; } //C.當商品組的全選框點選時,更新所有商品的狀態 public void changeCurrentSellerAllProductsStatus ( int i, boolean isSelected){ ShoppingBean.DataBean dataBean = list.get(i); List<ShoppingBean.DataBean.ListBean> beans = dataBean.getList(); for (int j = 0; j < beans.size(); j++) { ShoppingBean.DataBean.ListBean bean = beans.get(j); bean.setSelected(isSelected ? 1 : 0); } } //C.當商家子條目的全選框選中時,更新其狀態 public void changeCurrentProductStatus ( int i, int i1){ ShoppingBean.DataBean dataBean = list.get(i); List<ShoppingBean.DataBean.ListBean> list1 = dataBean.getList(); ShoppingBean.DataBean.ListBean listBean = list1.get(i1); listBean.setSelected(listBean.getSelected() == 0 ? 1 : 0); } //C.設定所有商品的狀態 public void changeAllProductStatus (boolean selected){ for (int x = 0; x < list.size(); x++) { ShoppingBean.DataBean dataBean = list.get(x); List<ShoppingBean.DataBean.ListBean> list1 = dataBean.getList(); for (int j = 0; j < list1.size(); j++) { list1.get(j).setSelected(selected ? 1 : 0); } } } //C.當加減器被點選時,呼叫,改變裡面當前商品的數量 引數1定位那個商家 引數2定位哪個商品 引數3定位改變具體的數量是多少 public void changeCurrentProductNumber (int i, int i1, int number){ ShoppingBean.DataBean dataBean = list.get(i); List<ShoppingBean.DataBean.ListBean> list = dataBean.getList(); ShoppingBean.DataBean.ListBean listBean = list.get(i1); listBean.setNum(number); } //成員變數 OnCartListChangeListener mOnCartListChangeListener; //D.方法的set public void setOnCartListChangeListener (OnCartListChangeListener onCartListChangeListener){ mOnCartListChangeListener = onCartListChangeListener; } public interface OnCartListChangeListener { //當商家的checkBox點選時回撥 void onSellerCheckedChange(int i); //當點選子條目商品的CheckBox回撥 void onProductCheckedChange(int i, int i1); //當點選加減按鈕的回撥 void onProducNumberChange(int i, int i1, int number); } public static class ParentViewHolder { public CheckBox seller_cb; public TextView seller_name_tv; public ParentViewHolder(View rootView) { seller_cb = rootView.findViewById(R.id.seller_cb); seller_name_tv = rootView.findViewById(R.id.seller_name_tv); } } public static class ChildViewHolder { public CheckBox child_cb; public ImageView product_icon_iv; public TextView product_title_name_tv; public TextView product_price_tv; public AddSubView add_remove_view; public ChildViewHolder(View rootView) { child_cb = rootView.findViewById(R.id.child_cb); product_icon_iv = rootView.findViewById(R.id.product_icon_iv); product_title_name_tv = rootView.findViewById(R.id.product_title_name_tv); product_price_tv = rootView.findViewById(R.id.product_price_tv); add_remove_view = rootView.findViewById(R.id.add_remove_view); } } @Override public boolean isChildSelectable ( int groupPosition, int childPosition){ return false; } @Override public Object getGroup ( int groupPosition){ return null; } @Override public Object getChild ( int groupPosition, int childPosition){ return null; } @Override public long getGroupId ( int groupPosition){ return 0; } @Override public long getChildId ( int groupPosition, int childPosition){ return 0; } @Override public boolean hasStableIds () { return false; } }
以下是佈局
activity_main.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".view.MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="購 物 車"
android:textSize="30sp"
android:textColor="#f00"
android:textStyle="bold"
android:gravity="center"
android:background="#fffc"
/>
<ExpandableListView
android:id="@+id/el_cart"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="9" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:background="#94cc"
android:layout_weight="1"
android:gravity="center_vertical">
<CheckBox
android:id="@+id/cb_cart_all_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:text="全選" />
<TextView
android:id="@+id/tv_cart_total_price"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="20dp"
android:textSize="30sp"
android:textColor="#f00"
android:text="合計:¥0.00" />
<Button
android:id="@+id/btn_cart_pay"
android:layout_width="120dp"
android:layout_height="match_parent"
android:textSize="20sp"
android:text="去結算[0]"
android:background="#cc4"
android:textStyle="bold"/>
</LinearLayout>
</LinearLayout>
item_cart_parent.xml商家
<?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:gravity="center_vertical"
android:orientation="horizontal">
<CheckBox
android:id="@+id/seller_cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/seller_name_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:textStyle="bold"
/>
</LinearLayout>
item_cart_child.xml商品
<?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:gravity="center_vertical"
android:orientation="horizontal">
<CheckBox
android:id="@+id/child_cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/product_icon_iv"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginLeft="20dp"
android:scaleType="centerCrop"
android:src="@color/colorPrimary" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="8"
android:orientation="vertical">
<TextView
android:id="@+id/product_title_name_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textSize="20sp"
android:text="商品標題" />
<TextView
android:id="@+id/product_price_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textSize="25sp"
android:textColor="#f00"
android:textStyle="bold"
android:text="¥0.0" />
</LinearLayout>
<com.zjh.administrat.shopping_cartdemo.view.AddSubView
android:id="@+id/add_remove_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
add_remove.xml加減數量
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="60dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:background="#99fff0"
android:gravity="center_vertical"
android:padding="2dp">
<TextView
android:id="@+id/sub_tv"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ffffff"
android:gravity="center"
android:text="-"
android:textSize="16sp" />
<TextView
android:id="@+id/product_number_tv"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:textSize="20sp"
android:textColor="#f00"
android:layout_weight="1"
android:background="#ffffff"
android:gravity="center"
android:text="1" />
<TextView
android:id="@+id/add_tv"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:layout_weight="1"
android:background="#ffffff"
android:gravity="center"
android:text="+"
android:textSize="16sp" />
</LinearLayout>