仿京东购物车

先在values文件夹下创建一个dimens布局文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <dimen name="left_space_pading">12dp</dimen>

</resources>

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context="com.example.cart_demo.MainActivity">

   <ExpandableListView
       android:id="@+id/elv_cart"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:layout_marginBottom="60dp">
   </ExpandableListView>

    <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/ck_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="wrap_content"
            android:layout_height="wrap_content"
            android:text="去结算(0)"
            android:background="#ff0000"
            android:textColor="#fff"
            />
    </LinearLayout>

</RelativeLayout>

二级列表的父布局 —— cart_parent_item_layout.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="60dp"
    android:gravity="center_vertical"
    android:paddingLeft="@dimen/left_space_pading"
    >

    <CheckBox
        android:id="@+id/seller_ck"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp"/>

    <TextView
        android:id="@+id/seller_name_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        />

</LinearLayout>

二级列表的子布局 —— cart_child_item_layout.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="120dp"
    android:gravity="center_vertical"
    android:paddingLeft="@dimen/left_space_pading"
    >

    <CheckBox
        android:id="@+id/child_ck"
        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:paddingLeft="@dimen/left_space_pading"
        android:orientation="vertical"
        android:layout_weight="1">

        <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.example.cart_demo.MyAddSubView
        android:id="@+id/add_remove_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        ></com.example.cart_demo.MyAddSubView>

</LinearLayout>

然后自定义加减器的布局 —— add_remove_view_layout.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:padding="2dp"
    android:layout_marginLeft="10dp"
    android:layout_gravity="center_vertical"
    android:background="#99000000"
    android:gravity="center_vertical">

    <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_weight="1"
        android:layout_marginLeft="2dp"
        android:gravity="center"
        android:background="#ffffff"
        android:text="1"
        />

    <TextView
        android:id="@+id/add_tv"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#ffffff"
        android:gravity="center"
        android:layout_marginLeft="2dp"
        android:text="+"
        android:textSize="16sp"
        />
</LinearLayout>

布局到这就ok了,随后就是自定义加减器的实现 —— MyAddSubView:

package com.example.cart_demo;

import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by DELL on 2018/6/29.
 */

public class MyAddSubView extends LinearLayout implements View.OnClickListener {

    private TextView sub_tv;
    private TextView product_number_tv;
    private TextView add_tv;
    private int num = 1;

    public MyAddSubView(Context context) {
        this(context, null);
    }

    public MyAddSubView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        View view = inflate(context, R.layout.add_remove_view_layout, 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 view) {

        switch (view.getId()) {

            case R.id.sub_tv:

                if (num > 1) {

                    --num;
                    product_number_tv.setText(num + "");

                    if (onNumChangerListener != null) {

                        onNumChangerListener.onNumChange(num);

                    } else {

                        Toast.makeText(getContext(), "商品数量不能小于1", Toast.LENGTH_SHORT).show();

                    }

                }

                break;

            case R.id.add_tv:

                ++num;

                product_number_tv.setText(num + "");

                if (onNumChangerListener != null) {

                    onNumChangerListener.onNumChange(num);

                }

                break;

        }

    }

    public int getNum() {

        return num;

    }

    public void setNum(int num) {

        this.num = num;

        product_number_tv.setText(num + "");

    }

    private OnNumChangerListener onNumChangerListener;

    public void setOnNumChangerListener(OnNumChangerListener onNumChangerListener) {

        this.onNumChangerListener = onNumChangerListener;

    }

    interface OnNumChangerListener {

        void onNumChange(int number);

    }

}

接下来核心的东西来了 —— MAdapter(二级列表的适配器):

package com.example.cart_demo;


import android.content.Context;
import android.graphics.Bitmap;
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.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;

import java.util.List;

/**
 * Created by DELL on 2018/6/29.
 */

public class MAdapter extends BaseExpandableListAdapter {

    private Context context;
    private List<Carts.DataBean> list;
    private final DisplayImageOptions options;

    public MAdapter(Context context, List<Carts.DataBean> list) {
        this.context = context;
        this.list = list;

        options = new DisplayImageOptions.Builder()
                .cacheInMemory(true)//使用内存缓存
                .cacheOnDisk(true)//使用磁盘缓存
                .bitmapConfig(Bitmap.Config.RGB_565)//设置图片色彩模式
                .imageScaleType(ImageScaleType.EXACTLY)//设置图片的缩放模式
                .build();
    }

    @Override
    public int getGroupCount() {
        return list == null ? 0 : list.size();
    }

    @Override
    public int getChildrenCount(int i) {
        return list.get(i).getList() == null ? 0 : list.get(i).getList().size();
    }

    @Override
    public Object getGroup(int i) {
        return null;
    }

    @Override
    public Object getChild(int i, int i1) {
        return null;
    }

    @Override
    public long getGroupId(int i) {
        return 0;
    }

    @Override
    public long getChildId(int i, int i1) {
        return 0;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(final int i, boolean b, View view, ViewGroup viewGroup) {
        ParentViewHolder parentHolder = null;
        if (view == null) {

            view = View.inflate(context, R.layout.cart_parent_item_layout, null);

            parentHolder = new ParentViewHolder();

            parentHolder.seller_ck = (CheckBox) view.findViewById(R.id.seller_ck);
            parentHolder.seller_name_tv = (TextView) view.findViewById(R.id.seller_name_tv);

            view.setTag(parentHolder);
        } else {

            parentHolder = (ParentViewHolder) view.getTag();

        }

        parentHolder.seller_name_tv.setText(list.get(i).getSellerName());

        boolean currentSellerAllProductSelected = isCurrentSellerAllProductSelected(i);
        parentHolder.seller_ck.setChecked(currentSellerAllProductSelected);
        parentHolder.seller_ck.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if(onCartListChangeListener != null){

                    onCartListChangeListener.onSellerCheckedChange(i);

                }

            }
        });

        return view;
    }

    //判断当前商家所有商品是否被选中
    public boolean isCurrentSellerAllProductSelected(int i) {

        Carts.DataBean dataBean = list.get(i);
        List<Carts.DataBean.ListBean> list1 = dataBean.getList();
        //List<Carts.DataBean.ListBean> list = this.list.get(i).getList();
        for (Carts.DataBean.ListBean listBean : list1) {

            if (listBean.getSelected() == 0) {

                return false;

            }

        }

        return true;

    }

    @Override
    public View getChildView(final int i, final int i1, boolean b, View view, ViewGroup viewGroup) {

        Carts.DataBean dataBean = list.get(i);
        List<Carts.DataBean.ListBean> list = dataBean.getList();
        Carts.DataBean.ListBean listBean = list.get(i1);

        ChildViewHolder childHolder = null;
        if (view == null) {

            view = View.inflate(context, R.layout.cart_child_item_layout, null);

            childHolder = new ChildViewHolder();

            childHolder.child_ck = (CheckBox) view.findViewById(R.id.child_ck);
            childHolder.product_icon_iv = (ImageView) view.findViewById(R.id.product_icon_iv);
            childHolder.product_title_name_tv = (TextView) view.findViewById(R.id.product_title_name_tv);
            childHolder.product_price_tv = (TextView) view.findViewById(R.id.product_price_tv);
            childHolder.add_remove_view = (MyAddSubView) view.findViewById(R.id.add_remove_view);

            view.setTag(childHolder);

        } else {

            childHolder = (ChildViewHolder) view.getTag();

        }

        //商品名称
        childHolder.product_title_name_tv.setText(listBean.getTitle());

        //商品单价
        childHolder.product_price_tv.setText(listBean.getPrice() + "");

        String[] strings = listBean.getImages().split("\\|");

        ImageLoader.getInstance().displayImage(strings[0],childHolder.product_icon_iv,options);

        childHolder.child_ck.setChecked(listBean.getSelected() == 1);
        childHolder.child_ck.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if(onCartListChangeListener != null){

                    onCartListChangeListener.onProductCheckedChange(i,i1);

                }

            }
        });

        childHolder.add_remove_view.setNum(listBean.getNum());
        childHolder.add_remove_view.setOnNumChangerListener(new MyAddSubView.OnNumChangerListener() {
            @Override
            public void onNumChange(int number) {

                if(onCartListChangeListener != null){

                    onCartListChangeListener.onProductNumberChange(i,i1,number);

                }

            }
        });

        return view;
    }

    @Override
    public boolean isChildSelectable(int i, int i1) {
        return false;
    }

    //所有商品是否被选中
    public boolean isAllProductsSelected() {

        for (int i = 0; i < list.size(); i++) {
            Carts.DataBean dataBean = list.get(i);

            List<Carts.DataBean.ListBean> list = dataBean.getList();

            for (int j = 0; j < list.size(); j++) {

                if (list.get(j).getSelected() == 0) {

                    return false;

                }

            }
        }
        return true;
    }


    //计算总价
    public float calculateTotalPrice(){

        float totalPrice = 0;

        for (int i = 0; i < list.size(); i++) {

            Carts.DataBean dataBean = list.get(i);

            List<Carts.DataBean.ListBean> list = dataBean.getList();

            for (int j = 0; j < list.size(); j++) {

                if(list.get(j).getSelected() == 1){

                    float price = list.get(j).getPrice();

                    int num = list.get(j).getNum();

                    totalPrice += price * num;

                }

            }

        }

        return totalPrice;

    }

    public int calculateTotalNumber(){

        int totalNumber = 0;
        for (int i = 0; i < list.size(); i++) {

            Carts.DataBean dataBean = list.get(i);

            List<Carts.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;

    }

    //当商家得checkbox被点击得时候调用,设置当前商家得所有商品得状态
    public void changeCurrentSellerAllProductsStatus(int i, boolean isSelected){

        Carts.DataBean dataBean = list.get(i);

        List<Carts.DataBean.ListBean> list = dataBean.getList();

        for (int j = 0; j < list.size(); j++) {

            Carts.DataBean.ListBean listBean = list.get(j);

            listBean.setSelected(isSelected ? 1 : 0);

        }

    }

    //当商品得checkbox被点击得时候调用,改变当前商品状态
    public void changeCurrentProductStatus(int i, int i1){

        Carts.DataBean dataBean = list.get(i);

        List<Carts.DataBean.ListBean> list = dataBean.getList();

        Carts.DataBean.ListBean listBean = list.get(i1);

        listBean.setSelected(listBean.getSelected() == 0 ? 1 : 0);

    }

    //当加减器被点击得时候调用,改变当前商品得数量
    public void changeCurrentProductNumber(int i, int i1, int number){

        Carts.DataBean dataBean = list.get(i);

        List<Carts.DataBean.ListBean> list = dataBean.getList();

        Carts.DataBean.ListBean listBean = list.get(i1);

        listBean.setNum(number);
    }


    //设置所有商品得状态
    public void changeAllProductsStatus(boolean selected){

        for (int i = 0; i < list.size(); i++) {

            Carts.DataBean dataBean = list.get(i);

            List<Carts.DataBean.ListBean> list = dataBean.getList();

            for (int j = 0; j < list.size(); j++) {

                list.get(j).setSelected(selected ? 1 : 0);

            }

        }

    }

    class ParentViewHolder {

        public CheckBox seller_ck;
        public TextView seller_name_tv;

    }

    class ChildViewHolder {

        public CheckBox child_ck;
        public ImageView product_icon_iv;
        public TextView product_title_name_tv;
        public TextView product_price_tv;
        public MyAddSubView add_remove_view;

    }

    private OnCartListChangeListener onCartListChangeListener;

    public void setOnCartListChangeListener(OnCartListChangeListener onCartListChangeListener){

        this.onCartListChangeListener = onCartListChangeListener;
    }

    public interface OnCartListChangeListener{

        void onSellerCheckedChange(int i);

        void onProductCheckedChange(int i, int i1);

        void onProductNumberChange(int i, int i1, int number);

    }
}

最后MainActivity的实现:

package com.example.cart_demo;

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.google.gson.Gson;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    private ExpandableListView elv_cart;
    private CheckBox ck_cart_all_select;
    private TextView tv_cart_total_price;
    private Button btn_cart_pay;
    private MAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
    }

    private void initData() {
        String url = "https://www.zhaoapi.cn/product/getCarts";
        Map<String, String> map = new HashMap<>();
        map.put("uid", "71");
        OkhttpUtils.getInstance().doPost(url, map, new OkhttpUtils.OkCallback() {
            @Override
            public void onResponse(String json) {

                Gson gson = new Gson();
                Carts carts = gson.fromJson(json, Carts.class);
                String code = carts.getCode();

                if ("0".equalsIgnoreCase(code)) {

                    List<Carts.DataBean> data = carts.getData();
                    adapter = new MAdapter(MainActivity.this, data);
                    adapter.setOnCartListChangeListener(new MAdapter.OnCartListChangeListener() {
                        @Override
                        public void onSellerCheckedChange(int i) {

                            boolean currentSellerAllProductSelected = adapter.isCurrentSellerAllProductSelected(i);
                            adapter.changeCurrentSellerAllProductsStatus(i, !currentSellerAllProductSelected);
                            adapter.notifyDataSetChanged();

                            //刷新底部数据
                            refreshSelectedAndTotalPriceAndTotalNumber();
                        }

                        @Override
                        public void onProductCheckedChange(int i, int i1) {

                            adapter.changeCurrentProductStatus(i, i1);

                            adapter.notifyDataSetChanged();

                            //刷新底部数据
                            refreshSelectedAndTotalPriceAndTotalNumber();

                        }

                        @Override
                        public void onProductNumberChange(int i, int i1, int number) {

                            adapter.changeCurrentProductNumber(i, i1, number);

                            adapter.notifyDataSetChanged();

                            //刷新底部数据
                            refreshSelectedAndTotalPriceAndTotalNumber();

                        }
                    });

                    elv_cart.setAdapter(adapter);

                    //展开二级列表
                    for (int i = 0; i < data.size(); i++) {

                        elv_cart.expandGroup(i);

                    }

                    //刷新底部数据
                    refreshSelectedAndTotalPriceAndTotalNumber();

                }
            }

            @Override
            public void onFailure(Exception e) {

            }
        });
    }

    //刷新checkbox状态和总价和总数量
    private void refreshSelectedAndTotalPriceAndTotalNumber() {

        //判断是否所有的商品都被选中
        boolean allProductsSelected = adapter.isAllProductsSelected();

        ck_cart_all_select.setChecked(allProductsSelected);

        //计算总价
        float price = adapter.calculateTotalPrice();
        tv_cart_total_price.setText("总价:" + price);

        //计算总数量
        int i = adapter.calculateTotalNumber();
        btn_cart_pay.setText("去结算(" + i + ")");

    }


    private void initView() {
        elv_cart = findViewById(R.id.elv_cart);
        ck_cart_all_select = findViewById(R.id.ck_cart_all_select);
        tv_cart_total_price = findViewById(R.id.tv_cart_total_price);
        btn_cart_pay = findViewById(R.id.btn_cart_pay);

        ck_cart_all_select.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                boolean allProductsSelected = adapter.isAllProductsSelected();

                adapter.changeAllProductsStatus(!allProductsSelected);

                adapter.notifyDataSetChanged();

                //刷新底部数据
                refreshSelectedAndTotalPriceAndTotalNumber();
            }
        });
    }
}

猜你喜欢

转载自blog.csdn.net/GaoYiranBlog/article/details/80857820