\"在这里插入图片描述\"

1.首先 导入依赖 权限

  (1) /*retrofit网络请求*/
    implementation \'com.squareup.retrofit2:retrofit:2.1.0\'
    implementation \'com.squareup.retrofit2:converter-gson:2.1.0\'
    /*eventbus传值*/
    implementation \'org.greenrobot:eventbus:3.0.0\'
    /*RxAndroid所依赖的库*/
    implementation \'com.squareup.retrofit2:adapter-rxjava:2.1.0\'
    implementation \'io.reactivex:rxandroid:1.2.1\'
    implementation \'io.reactivex:rxjava:1.1.6\'
    /*fresco图片处理*/
    implementation \'com.facebook.fresco:fresco:1.11.0\'

(2)网络权限
<uses-permission android:name=\"android.permission.INTERNET\"/>

(3)Fresco初始化(创建一个App继承Application,写出他的onCreate的方法,写下变一句话就行了)
 Fresco.initialize(this);

(4)清单文件注册  name

2.自定义加减器
(1)布局:

<?  version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout
     ns:android=\"http://schemas.android.com/apk/res/android\"
    android:layout_width=\"60dp\"
    android:layout_height=\"30dp\"
    android:orientation=\"horizontal\">
    <TextView
        android:layout_width=\"0dp\"
        android:layout_height=\"match_parent\"
        android:layout_weight=\"1\"
        android:text=\"-\"
        android:gravity=\"center\"
        android:id=\"@+id/sub_tv\"
        android:textSize=\"16sp\"/>
    <TextView
        android:layout_width=\"0dp\"
        android:layout_height=\"match_parent\"
        android:layout_weight=\"1\"
        android:text=\"1\"
        android:gravity=\"center\"
        android:background=\"#eae2e2\"
        android:id=\"@+id/product_number_tv\"/>
    <TextView
        android:layout_width=\"0dp\"
        android:layout_height=\"match_parent\"
        android:layout_weight=\"1\"
        android:text=\"+\"
        android:gravity=\"center\"
        android:id=\"@+id/add_tv\"
        android:textSize=\"16sp\"/>

</LinearLayout>

(2)主要代码:

public class MyAddSubView extends LinearLayout implements View. Listener {

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

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

    public MyAddSubView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyAddSubView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        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.set Listener(this);
        add_tv.set Listener(this);
    }


    @Override
    public void  (View v) {
        switch (v.getId()) {
            case R.id.sub_tv:
                if (number > 1) {
                    --number;
                    product_number_tv.setText(number + \"\");
                    if (onNumberChangeListener != null) {
                        onNumberChangeListener.onNumberChange(number);
                    }
                } else {
                    Toast.makeText(getContext(), \"不能再少了\", Toast.LENGTH_SHORT).show();
                }
                break;


            case R.id.add_tv:
                ++number;
                product_number_tv.setText(number + \"\");
                if (onNumberChangeListener != null) {
                    onNumberChangeListener.onNumberChange(number);
                }
                break;
        }
    }


    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
        product_number_tv.setText(number + \"\");
    }

    OnNumberChangeListener onNumberChangeListener;

    public void setOnNumberChangeListener(OnNumberChangeListener onNumberChangeListener) {
        this.onNumberChangeListener = onNumberChangeListener;
    }

    public interface OnNumberChangeListener {
        void onNumberChange(int num);
    }
}

3.MainActivity主页面
(1)主页面布局:

<?  version=\"1.0\" encoding=\"utf-8\"?>
<RelativeLayout
     ns:android=\"http://schemas.android.com/apk/res/android\"
     ns:app=\"http://schemas.android.com/apk/res-auto\"
     ns:tools=\"http://schemas.android.com/tools\"
    android:layout_width=\"match_parent\"
    android:layout_height=\"match_parent\"
    tools:context=\".MainActivity\">


    <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)主页面代码:

package com.bawie.shopcart3;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ExpandableListView;
import android.widget.TextView;

import com.bawie.shopcart3.adapter.ShopAdapter;
import com.bawie.shopcart3.bean.ShopBean;
import com.bawie.shopcart3.presenter.ShopPresenter;
import com.bawie.shopcart3.view.ShopView;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.List;

public class MainActivity extends AppCompatActivity implements  ShopView {

    private ExpandableListView el_cart;
    private CheckBox cb_cart_all_select;
    private TextView tv_cart_total_price;
    private Button btn_cart_pay;
    private ShopAdapter mShopAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
        if (!EventBus.getDefault().isRegistered(true)){
            EventBus.getDefault().register(this);
        }

    }

    private void initData() {
        ShopPresenter shopPresenter = new ShopPresenter(this);
        shopPresenter.success(\"71\");
    }
    @Override
    public void success(ShopBean shopBean) {
        List<ShopBean.DataBean> data = shopBean.getData();
        mShopAdapter = new ShopAdapter(data, MainActivity.this);
        el_cart.setAdapter(mShopAdapter);
        //展开二级列表
        for (int i = 0; i < data.size(); i++) {
            el_cart.expandGroup(i);
        }
    }

    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.set Listener(new View. Listener() {
            @Override
            public void  (View v) {
                //获取当前的条目状态
                boolean allCheckbox = mShopAdapter.isAllCheckbox();
                //给条目赋值
                mShopAdapter.isAllCheckBox(!allCheckbox);
                //刷新
                mShopAdapter.notifyDataSetChanged();
            }
        });
    }
    @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
    public void onMessageEvent(CountPrice countPrice){
        //总价
        tv_cart_total_price.setText(countPrice.getPrice()+\"\");
        //数量
        btn_cart_pay.setText(\"去结算(\"+countPrice.getCount()+\")\");
    }
    @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
    public void onMessageEvent(MessageEvent messageEvent){
        cb_cart_all_select.setChecked(messageEvent.isCheck());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //销毁EventBus
        if (EventBus.getDefault().isRegistered(true)){
            EventBus.getDefault().unregister(this);
        }
    }
}

4.二级列表适配器层
(1)适配器父布局:

<?  version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout
     ns: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=\"MMM\"/>
</LinearLayout>

(2)适配器子布局:

<?  version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout  ns:android=\"http://schemas.android.com/apk/res/android\"
    android:layout_width=\"match_parent\"
    android:layout_height=\"120dp\"
     ns:app=\"http://schemas.android.com/apk/res-auto\"
    android:gravity=\"center_vertical\">


    <CheckBox
        android:id=\"@+id/child_cb\"
        android:layout_width=\"wrap_content\"
        android:layout_height=\"wrap_content\" />

    <com.facebook.drawee.view.SimpleDraweeView
        android:id=\"@+id/product_icon_iv\"
        android:layout_width=\"80dp\"
        android:layout_height=\"80dp\"
        android:layout_marginLeft=\"20dp\"
        app:placeholderImage=\"@mipmap/ic_launcher\"/>
  

    <LinearLayout
        android:layout_width=\"wrap_content\"
        android:layout_height=\"wrap_content\"
        android:layout_weight=\"1\"
        android:orientation=\"vertical\">

        <TextView
            android:id=\"@+id/product_ _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.shopcart3.MyAddSubView
        android:id=\"@+id/add_remove_view\"
        android:layout_width=\"wrap_content\"
        android:layout_height=\"wrap_content\"
        android:layout_marginRight=\"10dp\" />

</LinearLayout>

(3)适配器代码:

package com.bawie.shopcart3.adapter;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget. ExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.TextView;

import com.bawie.shopcart3.CountPrice;
import com.bawie.shopcart3.MessageEvent;
import com.bawie.shopcart3.MyAddSubView;
import com.bawie.shopcart3.R;
import com.bawie.shopcart3.bean.ShopBean;
import com.facebook.drawee.view.SimpleDraweeView;

import org.greenrobot.eventbus.EventBus;

import java.util.List;

/**
 * date:2018/12/20
 * author:KK(别来无恙)
 * function:
 */
public class ShopAdapter extends  ExpandableListAdapter {

    private List<ShopBean.DataBean> mList;
    private Context mContext;

    public ShopAdapter(List<ShopBean.DataBean> list, Context context) {
        mList = list;
        mContext = context;
    }

    @Override
    public int getGroupCount() {
        return mList.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return mList.get(groupPosition).getList().size();
    }

    @Override
    public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        final OneViewHolder oneViewHolder;
        if (convertView == null) {
            convertView = View.inflate(mContext, R.layout.adapter_one, null);
            oneViewHolder = new OneViewHolder(convertView);
            convertView.setTag(oneViewHolder);
        } else {
            oneViewHolder = (OneViewHolder) convertView.getTag();
        }
        oneViewHolder.seller_name_tv.setText(mList.get(groupPosition).getSellerName());
        //判断所有的子条目是否选中
        boolean cildChange = isCildChange(groupPosition);
        //如果子条目选中  商家选中
        oneViewHolder.seller_cb.setChecked(cildChange);
        oneViewHolder.seller_cb.set Listener(new View. Listener() {
            @Override
            public void  (View v) {
                //获取当前的状态值
                boolean checked = oneViewHolder.seller_cb.isChecked();
                //调用控制子条目全选
                isCheckChange(groupPosition,checked);
                //计算总价和数量
                EventBus.getDefault().post(jiSuan());
                //刷新适配器
                notifyDataSetChanged();
            }
        });
        return convertView;
    }

    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        final TwoViewHolder twoViewHolder;
        if (convertView == null) {
            convertView = View.inflate(mContext, R.layout.adapter_two, null);
            twoViewHolder = new TwoViewHolder(convertView);
            convertView.setTag(twoViewHolder);
        }else {
            twoViewHolder = (TwoViewHolder) convertView.getTag();
        }
        List<ShopBean.DataBean.ListBean> list = mList.get(groupPosition).getList();
        final ShopBean.DataBean.ListBean listBean = list.get(childPosition);
        //头像
        String images = listBean.getImages();
        String[] split = images.split(\"!\");
        twoViewHolder.product_icon_iv.setImageURI(split[0]);
        //标题
        twoViewHolder.product_ _name_tv.setText(listBean.get ());
        //价格
        twoViewHolder.product_price_tv.setText(\"¥\"+listBean.getPrice());
        //设置加减器的数量
        twoViewHolder.add_remove_view.setNumber(listBean.getNum());
        //子条目的选中状态
        twoViewHolder.child_cb.setChecked(listBean.getSelected() == 1);
        //加减器的监听
        twoViewHolder.add_remove_view.setOnNumberChangeListener(new MyAddSubView.OnNumberChangeListener() {
            @Override
            public void onNumberChange(int num) {
                //设置加减器的值
                numBer(groupPosition,childPosition,num);
                EventBus.getDefault().post(jiSuan());
                //更新适配器
                notifyDataSetChanged();
            }
        });
        twoViewHolder.child_cb.set Listener(new View. Listener() {
            @Override
            public void  (View v) {
                //获取当前的状态值
                boolean checked = twoViewHolder.child_cb.isChecked();
                if (checked){
                    listBean.setSelected(1);
                }else {
                    listBean.setSelected(0);
                }
                EventBus.getDefault().post(jiSuan());
                notifyDataSetChanged();
            }
        });
        return convertView;
    }

    /**
     * 通过一级列表控制二级列表
     */
    private void isCheckChange(int i,boolean flag){
        ShopBean.DataBean dataBean = mList.get(i);
        List<ShopBean.DataBean.ListBean> list = dataBean.getList();
        for (int j = 0; j < list.size(); j++) {
            list.get(j).setSelected(flag?1:0);
        }
    }

    /**
     * 判断所有的复选框是否选中
     */
    public boolean isAllCheckbox(){
        for (int i = 0; i < mList.size(); i++) {
            ShopBean.DataBean dataBean = mList.get(i);
            List<ShopBean.DataBean.ListBean> list = dataBean.getList();
            for (int j = 0; j < list.size(); j++) {
                if (list.get(j).getSelected() == 0){
                    //等于0 就是没选中
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 判断所有的子条目是否选中
     */
    public boolean isCildChange(int groupPosition){
        ShopBean.DataBean dataBean = mList.get(groupPosition);
        List<ShopBean.DataBean.ListBean> list = dataBean.getList();
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getSelected() == 0){
                //等于0 就是没选中
                return false;
            }
        }
        return true;
    }

    /**
     * 判断全选框是否选中
     */
    public void isAllCheckBox(boolean flag){
        for (int i = 0; i < mList.size(); i++) {
            ShopBean.DataBean dataBean = mList.get(i);
            List<ShopBean.DataBean.ListBean> list = dataBean.getList();
            for (int j = 0; j < list.size(); j++) {
                list.get(j).setSelected(flag?1:0);
            }
        }
        EventBus.getDefault().post(jiSuan());
    }

    /**
     * 设置加减器的值
     */
    public void numBer(int groupPosition,int childPosition,int num){
        ShopBean.DataBean dataBean = mList.get(groupPosition);
        List<ShopBean.DataBean.ListBean> list = dataBean.getList();
        list.get(childPosition).setNum(num);
    }

    /**
     * 判断全选框
     */
    public void isQuanXuan(boolean flag){
        MessageEvent messageEvent = new MessageEvent(flag);
        EventBus.getDefault().post(messageEvent);
    }
    private CountPrice jiSuan() {
        int price = 0;
        int num = 0;
        int s = 1;
        for (int i = 0; i < mList.size(); i++) {
            ShopBean.DataBean dataBean = mList.get(i);
            List<ShopBean.DataBean.ListBean> list = dataBean.getList();
            for (int j = 0; j < list.size(); j++) {
                ShopBean.DataBean.ListBean listBean = list.get(j);
                //只要选中的
                if (listBean.getSelected() == 1){
                    num += listBean.getNum();
                    price += listBean.getNum() * listBean.getPrice();
                }else {
                    s = 0;
                }
            }
        }
        if (s == 0){
            isQuanXuan(false);
        }else {
            isQuanXuan(true);
        }
        CountPrice countPrice = new CountPrice();
        countPrice.setCount(num);
        countPrice.setPrice(price);
        return countPrice;
    }


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

    @Override
    public   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;
    }


    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return false;
    }

    public static class OneViewHolder {
        public View rootView;
        public CheckBox seller_cb;
        public TextView seller_name_tv;

        public OneViewHolder(View rootView) {
            this.rootView = rootView;
            this.seller_cb = (CheckBox) rootView.findViewById(R.id.seller_cb);
            this.seller_name_tv = (TextView) rootView.findViewById(R.id.seller_name_tv);
        }

    }

    public static class TwoViewHolder {
        public View rootView;
        public CheckBox child_cb;
        public SimpleDraweeView product_icon_iv;
        public TextView product_ _name_tv;
        public TextView product_price_tv;
        public MyAddSubView add_remove_view;

        public TwoViewHolder(View rootView) {
            this.rootView = rootView;
            this.child_cb = (CheckBox) rootView.findViewById(R.id.child_cb);
            this.product_icon_iv = (SimpleDraweeView) rootView.findViewById(R.id.product_icon_iv);
            this.product_ _name_tv = (TextView) rootView.findViewById(R.id.product_ _name_tv);
            this.product_price_tv = (TextView) rootView.findViewById(R.id.product_price_tv);
            this.add_remove_view = (MyAddSubView) rootView.findViewById(R.id.add_remove_view);
        }

    }
}

(5)适配器两个补助类:
①第一个MessageEvent :

public class MessageEvent {
    private boolean check;
    //有参  set和get方法

    public MessageEvent(boolean check) {
        this.check = check;
    }

    public boolean isCheck() {
        return check;
    }

    public void setCheck(boolean check) {
        this.check = check;
    }
}

②第二个CountPrice :

public class CountPrice {
    private int count;
    private int price;


    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

5.工具类:
(1)retrofitUtils网络请求:

public class RetrofitUtils {

    public static RetrofitService getInstance(){
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(3, TimeUnit.SECONDS)
                .readTimeout(3, TimeUnit.SECONDS)
                .writeTimeout(3, TimeUnit.SECONDS)
                .build();
        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                . Url(Constance.URL)
                .client(okHttpClient)
                .build();
        RetrofitService retrofitService = retrofit.create(RetrofitService.class);
        return retrofitService;
    }

}

(2)接口:

public class Constance {
    public static final String URL = \"http://www.zhaoapi.cn/\";
}

(3)RetrofitService拼接器:

public interface RetrofitService {
    @GET(\"product/getCarts\")
    Observable<ShopBean> getShop(@Query(\"uid\") String uid);

}

(4)bean类接口

http://www.zhaoapi.cn/product/getCarts?uid=71

6.MVP
(1)M:

public class ShopModel {
    public void success(Observer<ShopBean> observer,String uid){
        RetrofitService instance = RetrofitUtils.getInstance();
        instance.getShop(uid)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }
}

(2)View:

public interface ShopView {
    void success(ShopBean shopBean);
}

(3)Presenter:

public class ShopPresenter {
    private ShopModel mShopModel;
    private ShopView mShopView;

    public ShopPresenter(ShopView shopView) {
        mShopView = shopView;
        mShopModel = new ShopModel();
    }

    public void success(String uid){
        mShopModel.success(new Observer<ShopBean>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void  (Throwable e) {

            }

            @Override
            public void onNext(ShopBean shopBean) {
                mShopView.success(shopBean);
            }
        },uid);
    }
}

这就完成了我们的购物车!加油

收藏 打印