![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a2d624af2c5b8fbc9f557efff0e8f561.png)
1.主页面的布局
<?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">
<ExpandableListView
android:id="@+id/el_cart"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="60dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:background="#eeeeee"
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: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:text="合计:¥0.00" />
<Button
android:id="@+id/btn_cart_pay"
android:layout_width="100dp"
android:layout_height="match_parent"
android:text="去结算(0)" />
</LinearLayout>
</RelativeLayout>
2.自定义加减的布局
<?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:orientation="horizontal">
<TextView
android:id="@+id/sub_tv"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="-"
android:textSize="20sp"
android:gravity="center"/>
<TextView
android:id="@+id/product_number_tv"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="1"
android:textSize="20sp"
android:gravity="center"/>
<TextView
android:id="@+id/add_tv"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="+"
android:textSize="20sp"
android:gravity="center"/>
</LinearLayout>
3.商家的布局
<?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="60dp"
android:gravity="center_vertical">
<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="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="Name"/>
</LinearLayout>
4.商品的布局
<?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="wrap_content"
android:gravity="center_vertical">
<CheckBox
android:id="@+id/child_cb"
android:layout_marginLeft="20dp"
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="1"
android:orientation="vertical">
<TextView
android:id="@+id/product_title_name_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:text="商品标题" />
<TextView
android:id="@+id/product_price_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="¥0.0" />
</LinearLayout>
<com.bawie.www.shop2.MyAddSubView
android:id="@+id/add_remove_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp" />
</LinearLayout>
5.Main主页面
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
String url = "http://www.zhaoapi.cn/product/getCarts";
private ExpandableListView el_cart;
private CheckBox cb_cart_all_select;
private TextView tv_cart_total_price;
private Button btn_cart_pay;
private MyAdapter mMyAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
private void initData() {
Map<String,String> map = new HashMap<>();
map.put("uid","71");
NewsPresenter newsPresenter = new NewsPresenter();
newsPresenter.requestPresenter(url, map, new NewsPresenter.HttpPresenter() {
@Override
public void success(List<News.DataBean> data) {
//创建adapter
mMyAdapter = new MyAdapter(MainActivity.this, data);
mMyAdapter.setOnCartListChangeListener(new MyAdapter.onCartListChangeListener() {
@Override
public void onSellerCheckedChange(int groupPosition) {
//B.判断当前商家所有商品是否被选中 (一种是所有的都被选中,一种是没有所有的都选中)
boolean currentSellerAllProductSelected = mMyAdapter.isCurrentSellerAllProductSelected(groupPosition);
//提示为什么!currentSellerAllProductSelected取反,因为像灯一样,亮为true,暗为false,我先看灯是亮的,true,那么
//我要把他关了,取反把true改为false,然后设置进去,那么每一次我按钮的时候,都是拿到当前的状态,取反,再设置进去
//C.当商家的全选框点击时,更新所有商品全选的状态
mMyAdapter.changeCurrentSellerAllProductsStatus(groupPosition,!currentSellerAllProductSelected);
mMyAdapter.notifyDataSetChanged();
//刷新底部
refreshSelectedAndTotalPriceAndTotalNumber();
}
@Override
public void onProductCheckedChange(int groupPosition, int childPosition) {
//C.当商品的全选框选中时,更新商家选框的状态
mMyAdapter.changeCurrentProductStatus(groupPosition,childPosition);
mMyAdapter.notifyDataSetChanged();
refreshSelectedAndTotalPriceAndTotalNumber();
}
@Override
public void onProducNumberChange(int groupPosition, int childPosition, int number) {
//C.当加减器被点击时,改变里面当前商品的数量
mMyAdapter.changeCurrentProductNumber(groupPosition,childPosition,number);
mMyAdapter.notifyDataSetChanged();
refreshSelectedAndTotalPriceAndTotalNumber();
}
});
el_cart.setAdapter(mMyAdapter);
//展开二级列表
//展开二级列表
for(int x=0; x<data.size(); x++){
el_cart.expandGroup(x);
}
}
@Override
public void failed() {
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.cb_cart_all_select:
//B.底部有一个全选按钮的逻辑,也要判断,不过范围更大, 是所有的商品是否被选中
boolean allProductsSelected = mMyAdapter.isAllProductsSelected();
//C.当最底部的全选框选中时,更新所有商品全选框的状态
mMyAdapter.changeAllProductStatus(!allProductsSelected);
mMyAdapter.notifyDataSetChanged();
//刷新底部的数据显示
refreshSelectedAndTotalPriceAndTotalNumber();
break;
}
}
//B.刷新底部全选框,textVIew和Button的UI,改变了CheckBox状态,总价,总数量
private void refreshSelectedAndTotalPriceAndTotalNumber(){
//去判断是否所有的商品都被选中
//B.底部有一个全选按钮的逻辑,也要判断,不过范围更大, 是所有的商品是否被选中
boolean allProductsSelected = mMyAdapter.isAllProductsSelected();
//把这个值设置给checkBox
cb_cart_all_select.setChecked(allProductsSelected);
//计算总计
//B.计算所有商品总的价格
float totalPrice = mMyAdapter.calculateTotalPrice();
tv_cart_total_price.setText("总计"+totalPrice);
//计算总数量
//B.计算商品总的数量
int totalNumber = mMyAdapter.calculateTotalNumber();
btn_cart_pay.setText("去结算("+totalNumber+")");
}
private void initView() {
el_cart = (ExpandableListView) findViewById(R.id.el_cart);
cb_cart_all_select = (CheckBox) findViewById(R.id.cb_cart_all_select);
tv_cart_total_price = (TextView) findViewById(R.id.tv_cart_total_price);
btn_cart_pay = (Button) findViewById(R.id.btn_cart_pay);
cb_cart_all_select.setOnClickListener(this);
}
}
6.adapter
public class MyAdapter extends BaseExpandableListAdapter {
private Context mContext;
private List<News.DataBean> mSellerData;
public MyAdapter(Context context, List<News.DataBean> sellerData) {
mContext = context;
mSellerData = sellerData;
}
@Override
public int getGroupCount() {
return mSellerData.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return mSellerData.get(groupPosition).getList().size();
}
//商家
@Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
News.DataBean dataBean = mSellerData.get(groupPosition);
ParentViewHolder parentViewHolder;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.item_parent, null);
parentViewHolder = new ParentViewHolder(convertView);
convertView.setTag(parentViewHolder);
} else {
parentViewHolder = (ParentViewHolder) convertView.getTag();
}
//设置商家名称
parentViewHolder.seller_name_tv.setText(dataBean.getSellerName());
//B.判断当前商家所有商品是否被选中 (一种是所有的都被选中,一种是没有所有的都选中)
boolean currentSellerAllProductSeleted = isCurrentSellerAllProductSelected(groupPosition);
parentViewHolder.seller_cb.setChecked(currentSellerAllProductSeleted);
//设置点击事件
parentViewHolder.seller_cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/**
* 当商家的checkBox点击时回调
*/
mOnCartListChangeListener.onSellerCheckedChange(groupPosition);
}
});
return convertView;
}
//商品
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
News.DataBean dataBean = mSellerData.get(groupPosition);
List<News.DataBean.ListBean> list = dataBean.getList();
ChildViewHolder childViewHolder;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.item_child, null);
childViewHolder = new ChildViewHolder(convertView);
convertView.setTag(childViewHolder);
}else {
childViewHolder = (ChildViewHolder) convertView.getTag();
}
//设置图片并剪切
String images = list.get(childPosition).getImages();
String[] image = images.split("!");
Picasso.with(mContext).load(image[0]).into(childViewHolder.product_icon_iv);
//设置商家名称
childViewHolder.product_title_name_tv.setText(list.get(childPosition).getTitle());
//设置单价
childViewHolder.product_price_tv.setText(list.get(childPosition).getPrice() + "");
//设置复选框是否选中 1是选中
childViewHolder.child_cb.setChecked(list.get(childPosition).getSelected() == 1);
//设置内部的数量
childViewHolder.add_remove_view.setNumber(list.get(childPosition).getNum());
childViewHolder.child_cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/**
* 当点击子条目商品的CheckBox回调
*/
mOnCartListChangeListener.onProductCheckedChange(groupPosition,childPosition);
}
});
childViewHolder.add_remove_view.setOnNumberChangeListener(new MyAddSubView.OnNumberChangeListener() {
@Override
public void onNumberChange(int num) {
/**
* 当点击加减按钮的回调
*/
mOnCartListChangeListener.onProducNumberChange(groupPosition,childPosition,num);
}
});
return convertView;
}
B.写一些购物车的特有的方法//
/**
* B.判断当前商家所有商品是否被选中
* (一种是所有的都被选中,一种是没有所有的都选中)
*/
public boolean isCurrentSellerAllProductSelected(int groupPosition) {
//拿到对应组的数据
News.DataBean dataBean = mSellerData.get(groupPosition);
//拿到商家的所有商品数据,是一个集合
List<News.DataBean.ListBean> list = dataBean.getList();
for (News.DataBean.ListBean listBean : list) {
//判断这个组的所有商品是否被选中,如果有一个没有被选中,那么商家就是未选中状态
if (listBean.getSelected() == 0) {
return false;
}
}
return true;
}
/**
* B.底部有一个全选按钮的逻辑,也要判断,不过范围更大,
* 是所有的商品是否被选中
* (一种是所有的都被选中,一种是没有所有的都选中)
*/
public boolean isAllProductsSelected(){
for (int i = 0; i < mSellerData.size(); i++) {
News.DataBean dataBean = mSellerData.get(i);
List<News.DataBean.ListBean> list = dataBean.getList();
for (int j = 0; j < list.size(); j++) {
if (list.get(j).getSelected() == 0){
return false;
}
}
}
return true;
}
/**
* B.计算商品总的数量
*/
public int calculateTotalNumber(){
int totalNumber = 0;
for (int i = 0; i < mSellerData.size(); i++) {
News.DataBean dataBean = mSellerData.get(i);
List<News.DataBean.ListBean> list = dataBean.getList();
for (int j = 0; j < list.size(); j++) {
//商品数量只算选中
if (list.get(j).getSelected() == 1){
//拿到了商品的数量
int num = list.get(j).getNum();
totalNumber +=num;
}
}
}
return totalNumber;
}
/**
* B.计算所有商品总的价格
*/
public float calculateTotalPrice(){
float totalPrice = 0;
for (int i = 0; i < mSellerData.size(); i++) {
News.DataBean dataBean = mSellerData.get(i);
List<News.DataBean.ListBean> list = dataBean.getList();
for (int j = 0; j < list.size(); j++) {
//商品价格只算选中
if (list.get(j).getSelected() == 1){
//拿到商品的价格
float price = (float) list.get(j).getPrice()