1. 程式人生 > >MVP模式實現Android簡單購物車

MVP模式實現Android簡單購物車

retrofit+rxjava思想,並進行簡單的封裝.

效果圖:

V層:呼叫P層方法

P層:連線V層和M層,並在V層關閉檢視的時候實現解耦,呼叫M層方法獲取資料返回給V層

M層:獲取資料,供P層獲取呼叫

RetrofitUtil工具類:

import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitUtil {
    private static RetrofitUtil instener;
    private OkHttpClient okHttpClient;
    private Retrofit retrofit;

    private RetrofitUtil() {
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(5, TimeUnit.SECONDS)
                .writeTimeout(5, TimeUnit.SECONDS)
                .readTimeout(5, TimeUnit.SECONDS)
                .addInterceptor(logging)
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(Api.BASEURL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(okHttpClient)
                .build();
    }

    public static synchronized RetrofitUtil getInstener() {
        synchronized (RetrofitUtil.class) {
            if (instener == null) {
                instener = new RetrofitUtil();
            }
        }
        return instener;
    }

    public ApiService getCreate() {
        return retrofit.create(ApiService.class);
    }
}

ApiService:

import com.bwei.jiangbikuan.day0629.model.bean.CatagoryBean;
import com.bwei.jiangbikuan.day0629.model.bean.GetCartsBean;
import com.bwei.jiangbikuan.day0629.model.bean.ProductCatagoryBean;

import io.reactivex.Observable;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;

public interface ApiService {
    @GET("product/getCatagory")
    Observable<CatagoryBean> getCatagory();

    @FormUrlEncoded
    @POST("product/getProductCatagory")
    Observable<ProductCatagoryBean> getProductCatagory(@Field("cid") String cid);

    @FormUrlEncoded
    @POST("product/getCarts")
    Observable<GetCartsBean> getCarts(@Field("uid") String uid);
}

分類頁面:

V層:

mainactivity:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private FrameLayout myfl;
    private RadioGroup rg;
    private RadioButton rbClass;
    private RadioButton rbShop;
    private FragmentManager fragmentManager;
    private ClassFragment classFragment;
    private ShopFragment shopFragment;
    private int classFragmentcommit;
    private int shopFragmentcommit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化控制元件
        initView();
        //獲得fragment管理者
        fragmentManager = getSupportFragmentManager();
        //建立兩個模組fragment物件
        classFragment = new ClassFragment();
        shopFragment = new ShopFragment();
        //設定預設顯示fragment
        classFragmentcommit = fragmentManager.beginTransaction().replace(R.id.myfl, classFragment).commit();
    }

    private void initView() {
        myfl = (FrameLayout) findViewById(R.id.myfl);
        rg = (RadioGroup) findViewById(R.id.rg);
        rbClass = (RadioButton) findViewById(R.id.rb_class);
        rbShop = (RadioButton) findViewById(R.id.rb_shop);
        rbShop.setOnClickListener(this);
        rbClass.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            default:
                break;
            case R.id.rb_class:
                if (classFragmentcommit==0){
                    fragmentManager.beginTransaction().replace(R.id.myfl, classFragment).commit();
                    Toast.makeText(this, "分類建立", Toast.LENGTH_SHORT).show();
                }else{
                    fragmentManager.beginTransaction().show(classFragment);
                    Toast.makeText(this, "分類顯示", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.rb_shop:
                if (shopFragmentcommit==0) {
                    shopFragmentcommit = fragmentManager.beginTransaction().replace(R.id.myfl, shopFragment).commit();
                    Toast.makeText(this, "購物車建立", Toast.LENGTH_SHORT).show();
                }else{
                    fragmentManager.beginTransaction().show(shopFragment);
                    Toast.makeText(this, "購物車顯示", Toast.LENGTH_SHORT).show();
                }

                break;
        }
    }

}

ClassFragment :

public class ClassFragment extends Fragment implements CatagoryView, ProductCatagoryView {

    private RecyclerView mClassLeft;
    private ExpandableListView mClassRight;
    private CatagoryPreImp catagoryPreImp;
    private ProductCatagoryperImp productCatagoryperImp;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.activity_class, null);
        initView(view);
        //繫結
        catagoryPreImp = new CatagoryPreImp(this);
        catagoryPreImp.getCatagory();
        productCatagoryperImp = new ProductCatagoryperImp(this);
        return view;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        catagoryPreImp.closeView();
        productCatagoryperImp.closeView();
    }

    private void initView(View view) {
        mClassLeft = (RecyclerView) view.findViewById(R.id.class_left);
        mClassLeft.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
        mClassRight = (ExpandableListView) view.findViewById(R.id.class_right);
    }

    @Override
    public void showData(CatagoryBean catagoryBean) {
        final List<CatagoryBean.DataBean> list = catagoryBean.getData();
        final LeftAdapter leftAdapter = new LeftAdapter(getContext(), list);
        mClassLeft.setAdapter(leftAdapter);
        leftAdapter.changeBg(0, true);
        productCatagoryperImp.getProductCatagory(list.get(0).getCid() + "");
        leftAdapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(int position) {
                leftAdapter.changeBg(position, true);
                productCatagoryperImp.getProductCatagory(list.get(position).getCid() + "");
            }
        });
    }

    @Override
    public void showData(ProductCatagoryBean bean) {
        List<ProductCatagoryBean.DataBean> data = bean.getData();
        //存放父列表的資料
        List<String> groupList = new ArrayList<>();
        //存放子列表的資料
        List<List<ProductCatagoryBean.DataBean.ListBean>> chlidList = new ArrayList<>();
        //迴圈新增資料
        for (int i = 0; i < data.size(); i++) {
            String name = data.get(i).getName();
            List<ProductCatagoryBean.DataBean.ListBean> list = data.get(i).getList();
            groupList.add(name);
            chlidList.add(list);
        }
        //二級列表介面卡
        RightAdapter rightAdapter = new RightAdapter(getContext(), groupList, chlidList);
        mClassRight.setAdapter(rightAdapter);
        mClassRight.setGroupIndicator(null);
        mClassRight.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                return true;
            }
        });
        for (int i = 0; i < groupList.size(); i++) {
            mClassRight.expandGroup(i);
        }
    }
}

介面卡:

左側列表介面卡->LeftAdapter:

public class LeftAdapter extends RecyclerView.Adapter<LeftAdapter.LeftViewHolder> {
    private Context context;
    private List<CatagoryBean.DataBean> list;
    private LayoutInflater inflater;
    private OnItemClickListener mOnItemClickListener;

    public LeftAdapter(Context context, List<CatagoryBean.DataBean> list) {
        this.context = context;
        this.list = list;
        inflater = LayoutInflater.from(context);
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }

    @NonNull
    @Override
    public LeftViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.class_left_item, null);
        LeftViewHolder leftViewHolder = new LeftViewHolder(view);
        return leftViewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull LeftViewHolder holder, final int position) {
        CatagoryBean.DataBean dataBean = list.get(position);
        holder.leftText.setText(dataBean.getName());
        if (dataBean.isChecked()) {
            holder.leftText.setTextColor(Color.RED);
            holder.itemView.setBackgroundColor(0xFF66CCFF);
        } else {
            holder.leftText.setTextColor(Color.BLACK);
            holder.itemView.setBackgroundColor(Color.WHITE);
        }
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnItemClickListener != null) {
                    mOnItemClickListener.onItemClick(position);
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    class LeftViewHolder extends RecyclerView.ViewHolder {

        private final TextView leftText;

        public LeftViewHolder(View itemView) {
            super(itemView);
            leftText = (TextView) itemView.findViewById(R.id.left_text);
        }
    }

    //選中改變字型顏色和背景顏色
    public void changeBg(int position, boolean flag) {
        //還原所有的原本顏色
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setChecked(false);
        }
        //得到你所選擇的物件
        CatagoryBean.DataBean dataBean = list.get(position);
        dataBean.setChecked(flag);
        //重新整理頁面
        notifyDataSetChanged();
    }
}

右側列表介面卡->RightAdapter:

import android.content.Context;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;


import com.example.R;
import com.example.model.bean.ProductCatagoryBean;

import java.util.List;

public class RightAdapter extends BaseExpandableListAdapter {
    private Context context;
    private List<String> groupList;
    private List<List<ProductCatagoryBean.DataBean.ListBean>> chlidList;

    public RightAdapter(Context context, List<String> groupList, List<List<ProductCatagoryBean.DataBean.ListBean>> chlidList) {
        this.context = context;
        this.groupList = groupList;
        this.chlidList = chlidList;
    }

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

    @Override
    public int getChildrenCount(int groupPosition) {
        return 1;
    }

    @Override
    public Object getGroup(int groupPosition) {
        return groupList.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return chlidList.get(groupPosition).get(childPosition);
    }

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

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

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

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        GroupViewHolder groupViewHolder;
        if (convertView == null) {
            groupViewHolder = new GroupViewHolder();
            convertView = View.inflate(context, R.layout.elv_group_item, null);
            groupViewHolder.groupText = convertView.findViewById(R.id.group_text);
            convertView.setTag(groupViewHolder);
        } else {
            groupViewHolder = (GroupViewHolder) convertView.getTag();
        }
        String name = groupList.get(groupPosition);
        groupViewHolder.groupText.setText(name);
        return convertView;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ChildViewHolder childViewHolder;
        if (convertView == null) {
            childViewHolder = new ChildViewHolder();
            convertView = View.inflate(context, R.layout.elv_child_item, null);
            childViewHolder.child_rv = convertView.findViewById(R.id.child_rv);
            convertView.setTag(childViewHolder);
        } else {
            childViewHolder = (ChildViewHolder) convertView.getTag();
        }
        List<ProductCatagoryBean.DataBean.ListBean> listBeans = chlidList.get(groupPosition);
        childViewHolder.child_rv.setLayoutManager(new GridLayoutManager(context, 3, LinearLayoutManager.VERTICAL, false));
        //recycleView的介面卡
        ChildRvAdapter childRvAdapter = new ChildRvAdapter(context, listBeans);
        childViewHolder.child_rv.setAdapter(childRvAdapter);
        return convertView;
    }

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

    class GroupViewHolder {
        TextView groupText;
    }

    class ChildViewHolder {
        RecyclerView child_rv;
    }
}

右側子列表介面卡->ChildRvAdapter:

import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.example.R;
import com.example.model.bean.ProductCatagoryBean;
import com.facebook.drawee.view.SimpleDraweeView;

import java.util.List;

public class ChildRvAdapter extends RecyclerView.Adapter<ChildRvAdapter.ViewHolder> {
    private Context context;
    private List<ProductCatagoryBean.DataBean.ListBean> listBeans;
    private LayoutInflater inflater;

    public ChildRvAdapter(Context context, List<ProductCatagoryBean.DataBean.ListBean> listBeans) {
        this.context = context;
        this.listBeans = listBeans;
        inflater = LayoutInflater.from(context);
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.elv_child_rv_item, null);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        ProductCatagoryBean.DataBean.ListBean listBean = listBeans.get(position);
        holder.rvImage.setImageURI(Uri.parse(listBean.getIcon()));
        holder.rvText.setText(listBean.getName());

    }

    @Override
    public int getItemCount() {
        return listBeans.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {

        private final SimpleDraweeView rvImage;
        private final TextView rvText;

        public ViewHolder(View itemView) {
            super(itemView);
            rvImage = (SimpleDraweeView) itemView.findViewById(R.id.child_rv_img);
            rvText = (TextView) itemView.findViewById(R.id.child_rv_text);
        }
    }
}

P層:

CatagoryPreImp:

public class CatagoryPreImp implements ICatagory {
    private CatagoryView catagoryView;
    private CatagoryImp catagoryImp;

    public CatagoryPreImp(CatagoryView catagoryView) {
        //把V層作為引數傳進來,例項化M層,實現連線V層和M層
        this.catagoryView = catagoryView;
        catagoryImp = new CatagoryImp();
    }

    @Override
    public void getCatagory() {
        //呼叫M層方法,獲取資料
        catagoryImp.getCatagory(new CatagoryModel.OnCatagoryListener() {
            @Override
            public void onCatagoryListener(CatagoryBean catagoryBean) {
                catagoryView.showData(catagoryBean);
            }
        });
    }

    //解耦
    public void closeView(){
        if(catagoryView != null){
            catagoryView = null;
        }
    }
}

ProductCatagoryperImp:

import com.example.model.ProductCatagoryImp;
import com.example.model.bean.ProductCatagoryBean;
import com.example.model.inter.ProductCatagory;
import com.example.presenter.imp.ProductCatagoryper;
import com.example.view.fragment.inter.ProductCatagoryView;


public class ProductCatagoryperImp implements ProductCatagoryper {

    private ProductCatagoryView productCatagoryView;
    private final ProductCatagoryImp productCatagoryImp;

    public ProductCatagoryperImp(ProductCatagoryView productCatagoryView){
        this.productCatagoryView = productCatagoryView;
        productCatagoryImp = new ProductCatagoryImp();
    }

    @Override
    public void getProductCatagory(String cid) {
        productCatagoryImp.showData(cid, new ProductCatagory.ProductCatagoryListener() {
            @Override
            public void OnProductCatagoryBean(ProductCatagoryBean productCatagoryBean) {
                productCatagoryView.showData(productCatagoryBean);
            }
        });
    }
    //解耦
    public void closeView(){
        if(productCatagoryView != null){
            productCatagoryView = null;
        }
    }

}

介面:

ICatagory:

public interface ICatagory {
    void getCatagory();
}

ProductCatagoryper:

public interface ProductCatagoryper {
    void getProductCatagory(String cid);
}

M層:

CatagoryImp:

public class CatagoryImp implements CatagoryModel {
    @Override
    public void getCatagory(final OnCatagoryListener catagoryListener) {
        ApiService apiService = RetrofitUtil.getInstener().getCreate();
        apiService.getCatagory()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<CatagoryBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(CatagoryBean catagoryBean) {
                        catagoryListener.onCatagoryListener(catagoryBean);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("JBK", "onError: " + e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}

ProductCatagoryImp:

import android.util.Log;

import com.example.model.bean.ProductCatagoryBean;
import com.example.model.inter.ProductCatagory;
import com.example.net.RetrofitUtil;
import com.example.net.api.ApiService;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;


public class ProductCatagoryImp implements ProductCatagory {
    @Override
    public void showData(String cid, final ProductCatagoryListener productCatagoryListener) {
        ApiService apiService = RetrofitUtil.getInstener().getCreate();
        apiService.getProductCatagory(cid)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ProductCatagoryBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(ProductCatagoryBean productCatagoryBean) {
                        productCatagoryListener.OnProductCatagoryBean(productCatagoryBean);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("JBK", "onError: " + e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}

介面:

CatagoryModel:

public interface CatagoryModel {
    void getCatagory(OnCatagoryListener catagoryListener);

    interface OnCatagoryListener{
        void onCatagoryListener(CatagoryBean catagoryBean);
    }
}

ProductCatagory:

import com.example.model.bean.ProductCatagoryBean;


public interface ProductCatagory {
    void showData(String cid,ProductCatagoryListener productCatagoryListener);

    interface ProductCatagoryListener {
        void OnProductCatagoryBean(ProductCatagoryBean productCatagoryBean);
    }
}

購物車頁面:

V層:

ShopFragment:

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.R;
import com.example.adapter.ShopElvAdapter;
import com.example.model.bean.GetCartsBean;
import com.example.model.bean.MessageEvent.MessageEvent;
import com.example.model.bean.MessageEvent.PriceAndNumEvent;
import com.example.model.bean.SellectBean;
import com.example.presenter.inter.GetCartsPreImp;
import com.example.view.fragment.inter.GetCartsView;

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

import java.util.ArrayList;
import java.util.List;

public class ShopFragment extends Fragment implements View.OnClickListener, GetCartsView {

    private GetCartsPreImp getCartsPreImp;
    private View view;
    private ExpandableListView mElv;
    /**
     * 全選
     */
    private CheckBox mCbAll;
    /**
     * 合計:
     */
    private TextView mTvMoney;
    /**
     * 去結算:
     */
    private TextView mTvTotal;
    private ShopElvAdapter shopElvAdapter;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.activity_shop, null);
        //調取P層.獲取資料
        getCartsPreImp = new GetCartsPreImp(this);
        getCartsPreImp.showData("13180");
        //初始化控制元件
        initView(view);
        //註冊EventBus
        EventBus.getDefault().register(this);
        return view;
    }

    //解耦
    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        getCartsPreImp.closeView();
    }

    private void initView(View view) {
        mElv = (ExpandableListView) view.findViewById(R.id.elv);
        mCbAll = (CheckBox) view.findViewById(R.id.cbAll);
        mCbAll.setOnClickListener(this);
        mTvMoney = (TextView) view.findViewById(R.id.tvMoney);
        mTvTotal = (TextView) view.findViewById(R.id.tvTotal);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            default:
                break;
            case R.id.cbAll:
                shopElvAdapter.changeAllState(mCbAll.isChecked());
                break;
        }
    }

    @Override
    public void showData(GetCartsBean getCartsBean) {
        //存放商家的集合
        List<SellectBean> groupList = new ArrayList<>();
        //存放商品的集合
        List<List<GetCartsBean.DataBean.ListBean>> childList = new ArrayList();
        List<GetCartsBean.DataBean> data = getCartsBean.getData();
        for (int i = 0; i < data.size(); i++) {
            GetCartsBean.DataBean dataBean = data.get(i);
            String sellerName = dataBean.getSellerName();
            boolean checked = dataBean.isChecked();
            String sellerid = dataBean.getSellerid();
            List<GetCartsBean.DataBean.ListBean> list = dataBean.getList();
            //存放資料
            SellectBean sellectBean = new SellectBean();
            sellectBean.setSellerid(sellerid);
            sellectBean.setSellerName(sellerName);
            sellectBean.setChecked(checked);
            //向List新增資料
            groupList.add(sellectBean);
            childList.add(list);
        }
        //介面卡
        shopElvAdapter = new ShopElvAdapter(getContext(), groupList, childList);
        mElv.setAdapter(shopElvAdapter);
        for (int i = 0; i < data.size(); i++) {
            mElv.expandGroup(i);
        }
    }
    @Subscribe
    public void onMessage(PriceAndNumEvent priceAndNumEvent) {
        mTvMoney.setText("合計:" + priceAndNumEvent.getPrice());
        mTvTotal.setText("去結算:" + priceAndNumEvent.getNum());
    }

    @Subscribe
    public void onMessageFlag(MessageEvent event) {
        boolean flag = event.isFlag();
        mCbAll.setChecked(flag);
    }
}

介面:

GetCartsView:

import com.example.model.bean.GetCartsBean;

/**
 * Created by Administrator on 2018/7/2.
 */

public interface GetCartsView {
    void showData(GetCartsBean getCartsBean);
}

P層:

GetCartsPreImp:

import com.example.model.GetCartsImp;
import com.example.model.bean.GetCartsBean;
import com.example.model.inter.GetCarts;
import com.example.presenter.imp.GetCartsPre;
import com.example.view.fragment.inter.GetCartsView;

public class GetCartsPreImp implements GetCartsPre {

    private GetCartsView getCartsView;
    private final GetCartsImp getCartsImp;

    public GetCartsPreImp(GetCartsView getCartsView){
        this.getCartsView = getCartsView;
        getCartsImp = new GetCartsImp();
    }

    @Override
    public void showData(String uid) {
        getCartsImp.showData(uid, new GetCarts.GetCartsListener() {
            @Override
            public void onGetCartsListener(GetCartsBean getCartsBean) {
                getCartsView.showData(getCartsBean);
            }
        });
    }
    public void closeView() {
        if (getCartsView != null) {
            getCartsView = null;
        }
    }

}

介面:

GetCartsPre:

public interface GetCartsPre {
    void showData(String uid);
}

M層:

GetCartsImp:

import android.util.Log;

import com.example.model.bean.GetCartsBean;
import com.example.model.inter.GetCarts;
import com.example.net.RetrofitUtil;
import com.example.net.api.ApiService;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class GetCartsImp implements GetCarts {
    @Override
    public void showData(String uid, final GetCartsListener getCartsListener) {
        ApiService apiService = RetrofitUtil.getInstener().getCreate();
        apiService.getCarts(uid)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<GetCartsBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(GetCartsBean getCartsBean) {
                        getCartsListener.onGetCartsListener(getCartsBean);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("JBK", "onError: " + e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}

介面:

GetCarts:

import com.example.model.bean.GetCartsBean;

public interface GetCarts {
    void showData(String uid,GetCartsListener getCartsListener);

    interface GetCartsListener{
        void onGetCartsListener(GetCartsBean getCartsBean);
    }
}

介面卡:

ShopElvAdapter:

import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.TextView;

import com.example.R;
import com.example.model.bean.GetCartsBean;
import com.example.model.bean.MessageEvent.MessageEvent;
import com.example.model.bean.MessageEvent.PriceAndNumEvent;
import com.example.model.bean.SellectBean;
import com.example.view.fragment.AddSubView;
import com.facebook.drawee.view.SimpleDraweeView;

import org.greenrobot.eventbus.EventBus;

import java.util.List;

public class ShopElvAdapter extends BaseExpandableListAdapter {

    private Context context;
    private List<SellectBean> groupList;
    private List<List<GetCartsBean.DataBean.ListBean>> childList;

    public ShopElvAdapter(Context context, List<SellectBean> groupList, List<List<GetCartsBean.DataBean.ListBean>> childList) {
        this.context = context;
        this.groupList = groupList;
        this.childList = childList;
    }

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

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

    @Override
    public Object getGroup(int groupPosition) {
        return groupList.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return childList.get(groupPosition).get(childPosition);
    }

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

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

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

    @Override
    public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        final GroupViewHolder groupViewHolder;
        if (convertView == null) {
            groupViewHolder = new GroupViewHolder();
            convertView = View.inflate(context, R.layout.shop_elv_group, null);
            groupViewHolder.shop_group_cb = convertView.findViewById(R.id.shop_group_cb);
            convertView.setTag(groupViewHolder);
        } else {
            groupViewHolder = (GroupViewHolder) convertView.getTag();
        }
        final SellectBean sellectBean = groupList.get(groupPosition);
        groupViewHolder.shop_group_cb.setText(sellectBean.getSellerName());
        groupViewHolder.shop_group_cb.setChecked(sellectBean.isChecked());
        groupViewHolder.shop_group_cb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //判斷一級列表複選框的狀態,設定為true或者false
                sellectBean.setChecked(groupViewHolder.shop_group_cb.isChecked());
                //改變二級複選框的狀態
                checkedGroup(groupPosition, groupViewHolder.shop_group_cb.isChecked());
                //計算價格和數量
                PriceAndNumEvent priceAndNumEvent = computeMoneyAndNum();
                EventBus.getDefault().post(priceAndNumEvent);
                //判斷一級列表的狀態是否全部選中
                changeAllStart(isAllGroupSelect());
                //重新整理
                notifyDataSetChanged();
            }
        });
        return convertView;
    }

    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        final ChildViewHolder childViewHolder;
        if (convertView == null) {
            childViewHolder = new ChildViewHolder();
            convertView = View.inflate(context, R.layout.shop_elv_child, null);
            childViewHolder.shop_child_cb = convertView.findViewById(R.id.shop_child_cb);
            childViewHolder.shop_child_img = convertView.findViewById(R.id.shop_child_img);
            childViewHolder.shop_child_title = convertView.findViewById(R.id.shop_child_title);
            childViewHolder.shop_child_price = convertView.findViewById(R.id.shop_child_price);
            childViewHolder.addSubView = convertView.findViewById(R.id.addSubView);
            convertView.setTag(childViewHolder);
        } else {
            childViewHolder = (ChildViewHolder) convertView.getTag();
        }
        final GetCartsBean.DataBean.ListBean listBean = childList.get(groupPosition).get(childPosition);
        String[] split = listBean.getImages().split("\\|");
        childViewHolder.shop_child_cb.setChecked(listBean.isChecked());
        childViewHolder.shop_child_img.setImageURI(split[0]);
        childViewHolder.shop_child_title.setText(listBean.getTitle());
        childViewHolder.shop_child_title.setTextColor(Color.BLACK);
        childViewHolder.shop_child_price.setText("¥:" + listBean.getPrice() + "");
        childViewHolder.shop_child_price.setTextColor(Color.RED);
        childViewHolder.addSubView.setNum(listBean.getNum());

        //新增點選事件
        //checkBox的點選事件
        childViewHolder.shop_child_cb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //設定該條目中的CheckBox的狀態
                listBean.setChecked(childViewHolder.shop_child_cb.isChecked());
                //計算價格
                PriceAndNumEvent priceAndNumEvent = computeMoneyAndNum();
                EventBus.getDefault().post(priceAndNumEvent);
                //判斷當前checkbox的選擇狀態
                if (childViewHolder.shop_child_cb.isChecked()) {
                    //全部選中
                    if (isAllChlidSelected(groupPosition)) {
                        //改變一級列表的狀態
                        changeGroupState(groupPosition, true);
                        //改變全選狀態
                        changeAllStart(isAllGroupSelect());
                    }
                } else {
                    //如果沒有全部選中,一級列表的checkbox不選中
                    changeGroupState(groupPosition, false);
                    changeAllStart(isAllGroupSelect());
                }
                notifyDataSetChanged();
            }
        });
        //加減號
        childViewHolder.addSubView.setOnAddOrSubClickListener(new AddSubView.OnAddOrSubClickListener() {
            @Override
            public void onClickAdd(View view) {
                int num = listBean.getNum();
                num++;
                childViewHolder.addSubView.setNum(num);
                listBean.setNum(num);
                if (childViewHolder.shop_child_cb.isChecked()) {
                    PriceAndNumEvent priceAndNumEvent = computeMoneyAndNum();
                    EventBus.getDefault().post(priceAndNumEvent);
                }
            }

            @Override
            public void onClickSub(View view) {
                int num = listBean.getNum();
                if (num == 1) {
                    return;
                }
                num--;
                childViewHolder.addSubView.setNum(num);
                listBean.setNum(num);
                if (childViewHolder.shop_child_cb.isChecked()) {
                    PriceAndNumEvent priceAndNumEvent = computeMoneyAndNum();
                    EventBus.getDefault().post(priceAndNumEvent);
                }
            }
        });
        return convertView;
    }

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

    class GroupViewHolder {
        CheckBox shop_group_cb;
    }

    class ChildViewHolder {
        CheckBox shop_child_cb;
        SimpleDraweeView shop_child_img;
        TextView shop_child_title;
        TextView shop_child_price;
        AddSubView addSubView;
    }

    //改變一級列表的checkbox的狀態
    private void changeGroupState(int i, boolean flag) {
        SellectBean sellectBean = groupList.get(i);
        sellectBean.setChecked(flag);
    }

    //改變二級列表的checkbox的狀態
    private void changeChlidState(int i, boolean flag) {
        List<GetCartsBean.DataBean.ListBean> listBeans = childList.get(i);
        for (int j = 0; j < listBeans.size(); j++) {
            GetCartsBean.DataBean.ListBean listBean = listBeans.get(j);
            listBean.setChecked(flag);
        }
    }

    //判斷二級列表是否全部選中
    private boolean isAllChlidSelected(int i) {
        List<GetCartsBean.DataBean.ListBean> listBeans = childList.get(i);
        for (int j = 0; j < listBeans.size(); j++) {
            GetCartsBean.DataBean.ListBean listBean = listBeans.get(j);
            if (!listBean.isChecked()) {
                return false;
            }
        }
        return true;
    }

    //一級列表選中後,將對應的子類表選中
    private void checkedGroup(int position, boolean flag) {
        for (int i = 0; i < childList.get(position).size(); i++) {
            GetCartsBean.DataBean.ListBean listBean = childList.get(position).get(i);
            listBean.setChecked(flag);
        }
    }

    //判斷一級類表是否全部選中
    public boolean isAllGroupSelect() {
        for (int i = 0; i < childList.size(); i++) {
            SellectBean sellectBean = groupList.get(i);
            if (!sellectBean.isChecked()) {
                return false;
            }
        }
        return true;
    }

    //改變全選的狀態
    private void changeAllStart(boolean flag) {
        //EventBus傳值
        MessageEvent messageEvent = new MessageEvent();
        messageEvent.setFlag(flag);
        EventBus.getDefault().post(messageEvent);
    }

    //計算選中商品的價格和數量
    private PriceAndNumEvent computeMoneyAndNum() {
        double sumPrice = 0;
        int sumNum = 0;
        for (int i = 0; i < groupList.size(); i++) {
            List<GetCartsBean.DataBean.ListBean> listBeans = childList.get(i);
            for (int j = 0; j < listBeans.size(); j++) {
                GetCartsBean.DataBean.ListBean listBean = listBeans.get(j);
                //判斷是否選中
                if (listBean.isChecked()) {
                    sumNum += listBean.getNum();
                    sumPrice += listBean.getNum() * listBean.getPrice();
                }
            }
        }
        PriceAndNumEvent priceAndNumEvent = new PriceAndNumEvent();
        priceAndNumEvent.setPrice(sumPrice);
        priceAndNumEvent.setNum(sumNum);
        return priceAndNumEvent;
    }

    //設定全選,全不選
    public void changeAllState(boolean flag) {
        for (int i = 0; i < childList.size(); i++) {
            changeGroupState(i, flag);
            changeChlidState(i, flag);
        }
        //計算價格
        PriceAndNumEvent priceAndNumEvent = computeMoneyAndNum();
        EventBus.getDefault().post(priceAndNumEvent);
        notifyDataSetChanged();
    }
}

ChildRvAdapter:

import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.example.R;
import com.example.model.bean.ProductCatagoryBean;
import com.facebook.drawee.view.SimpleDraweeView;

import java.util.List;

public class ChildRvAdapter extends RecyclerView.Adapter<ChildRvAdapter.ViewHolder> {
    private Context context;
    private List<ProductCatagoryBean.DataBean.ListBean> listBeans;
    private LayoutInflater inflater;

    public ChildRvAdapter(Context context, List<ProductCatagoryBean.DataBean.ListBean> listBeans) {
        this.context = context;
        this.listBeans = listBeans;
        inflater = LayoutInflater.from(context);
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.elv_child_rv_item, null);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        ProductCatagoryBean.DataBean.ListBean listBean = listBeans.get(position);
        holder.rvImage.setImageURI(Uri.parse(listBean.getIcon()));
        holder.rvText.setText(listBean.getName());

    }

    @Override
    public int getItemCount() {
        return listBeans.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {

        private final SimpleDraweeView rvImage;
        private final TextView rvText;

        public ViewHolder(View itemView) {
            super(itemView);
            rvImage = (SimpleDraweeView) itemView.findViewById(R.id.child_rv_img);
            rvText = (TextView) itemView.findViewById(R.id.child_rv_text);
        }
    }
}

EventBus管理:

MessageEvent:

public class MessageEvent {
    private boolean flag;

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}

PriceAndNumEvent:

public class PriceAndNumEvent {
    private double price;
    private int num;

    public double getPrice() {
        return price;
    }

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

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }
}