MVP做二级购物车

这篇博客探讨了如何运用Model-View-Presenter(MVP)架构模式来设计和实现二级购物车的功能。文中详细介绍了在实现过程中依赖注入的重要性,以及在Model层、Adapter层的关键操作。

依赖注入

compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:26.+'

compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.google.code.gson:gson:2.8.2'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
compile 'com.jakewharton:butterknife-annotations:8.8.1'
compile 'com.jakewharton:butterknife:8.8.1'
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.google.code.gson:gson:2.8.2'
compile 'com.github.bumptech.glide:glide:3.7.0'


model

package aaaaa.myapplication.model;


import aaaaa.myapplication.bean.ShopBean;
import aaaaa.myapplication.okhttp.AbstractUiCallBack;
import aaaaa.myapplication.okhttp.OkhttpUtils;

/**
 * Created by muhanxi on 17/11/21.
 */

public class MainModel {



    public void getData(final MainModelCallBack callBack){


        OkhttpUtils.getInstance().asy(null, "http://120.27.23.105/product/getCarts?uid=100", new AbstractUiCallBack<ShopBean>() {

            public void success(ShopBean bean) {

                callBack.success(bean);
            }


            public void failure(Exception e) {

                callBack.failure(e);
            }
        });

    }


}
package aaaaa.myapplication.model;

import aaaaa.myapplication.bean.ShopBean;

/**
 * Created by muhanxi on 17/11/21.
 */

public interface MainModelCallBack {


    public void success(ShopBean bean);
    public void failure(Exception e);



}
presenter

package aaaaa.myapplication.presenter;


import aaaaa.myapplication.bean.ShopBean;
import aaaaa.myapplication.model.MainModel;
import aaaaa.myapplication.model.MainModelCallBack;
import aaaaa.myapplication.view.MainViewListener;

/**
 *
 * Created by muhanxi on 17/11/21.
 *
 */

public class MainPresenter {


    private MainViewListener listener;
    private MainModel mainModel;
    public MainPresenter(MainViewListener listener){
        this.listener = listener ;
        this.mainModel = new MainModel();
    }


    public void getData(){


        mainModel.getData(new MainModelCallBack() {

            @Override
            public void success(ShopBean bean) {

                if(listener != null){
                    listener.success(bean);
                }

            }

            @Override
            public void failure(Exception e) {

                if(listener != null){
                    listener.failure(e);
                }
            }
        });
    }


    /**
     * 防止内存泄漏
     */
    public void detach(){
        listener = null;
    }



}
view

package aaaaa.myapplication.view;


import aaaaa.myapplication.bean.ShopBean;

/**
 * Created by muhanxi on 17/11/21.
 */

public interface MainViewListener {


    public void success(ShopBean bean);
    public void failure(Exception e);

}
初始化

package aaaaa.myapplication;

import android.app.Application;

import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;

/**
 * Created by muhanxi on 17/11/21.
 */

public class IApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this).build();
        ImageLoader.getInstance().init(configuration);



    }
}
Main

package aaaaa.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import aaaaa.myapplication.bean.ShopBean;
import aaaaa.myapplication.presenter.MainPresenter;
import aaaaa.myapplication.view.MainViewListener;
import butterknife.BindView;
import butterknife.ButterKnife;

public class MainActivity extends Activity implements MainViewListener {



    CheckBox checkBoxAll;

    TextView thirdTotalprice;

    TextView thirdTotalnum;

    @BindView(R.id.third_pay_linear)
    LinearLayout thirdPayLinear;
    private MainPresenter presenter;
    private ShopAdapter adapter;
    private RecyclerView thirdRecyclerview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        thirdRecyclerview = findViewById(R.id.third_recyclerview);
         checkBoxAll=    findViewById(R.id.third_allselect);
        thirdTotalprice=    findViewById(R.id.third_totalprice);
        thirdTotalnum=    findViewById(R.id.third_totalnum);
        thirdPayLinear=    findViewById(R.id.third_pay_linear);
checkBoxAll.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        adapter.selectAll(checkBoxAll.isChecked());
    }
});
        presenter = new MainPresenter(this);
        presenter.getData();


        adapter = new ShopAdapter(this);
        LinearLayoutManager manager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);


        thirdRecyclerview.setLayoutManager(manager);
        thirdRecyclerview.setAdapter(adapter);


        adapter.setListener(new ShopAdapter.UpdateUiListener() {
            @Override
            public void setTotal(String total, String num,boolean allCheck) {

                checkBoxAll.setChecked(allCheck);
                thirdTotalnum.setText("数量:"+num);
                thirdTotalprice.setText("总价:¥"+total);
            }
        });


    }


    @Override
    public void success(ShopBean bean) {


        adapter.add(bean);


    }

    @Override
    public void failure(Exception e) {

        Toast.makeText(this, "error", Toast.LENGTH_SHORT).show();
    }





}
Plusview

package aaaaa.myapplication;

import android.content.Context;
import android.support.annotation.Nullable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;

/**
 * Created by muhanxi on 17/11/21.
 */


/**
 * 购物车加减号 自定义View
 */
public class PlusView extends LinearLayout {


    private EditText editText;
    private Button revserse;
    private Button add;
    private int mCount = 1 ;


    public PlusView(Context context) {
        super(context);
    }

    public PlusView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);



        View view =   LayoutInflater.from(context).inflate(R.layout.plus_layout,null,false);

        revserse = (Button) view.findViewById(R.id.revserse);
        add = (Button) view.findViewById(R.id.add);
        editText = (EditText) view.findViewById(R.id.content);


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

                //减号
                try {
                    String content =  editText.getText().toString().trim() ;
                    int count =  Integer.valueOf(content);

                    if(count > 1){
                        mCount = count-1;
                        editText.setText(mCount+"");
                        if(listener != null){
                            listener.click(mCount);
                        }
                    }


                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }


            }
        });


        add.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                //加号
                try {
                    String content =  editText.getText().toString().trim() ;
                    int count =  Integer.valueOf(content)+1;
                    mCount = count;

                    editText.setText(count+"");
                    if(listener != null){
                        listener.click(count);
                    }
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }
            }
        });


        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });


        addView(view);
    }

    public PlusView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }



    public void setEditText(int num){
        if(editText != null){
            editText.setText(num+"");
        }
    }

    public ClickListener listener;

    public void setListener(ClickListener listener){
        this.listener = listener;
    }

    /**
     * 加减号 点击事件
     */
    public interface ClickListener {
        public void click(int count);
    }





}

ShopAdapter

 
package aaaaa.ykle;


import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.nostra13.universalimageloader.core.ImageLoader;

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

import aaaaa.ykle.bean.ShopBean;


/**
 * Created by muhanxi on 17/11/21.
 */

public class ShopAdapter extends RecyclerView.Adapter<ShopAdapter.IViewHolder> {

    private Context context;

    private List<ShopBean.DataBean.ListBean> list;
    // 存放 商家的id 和 商家名称
    private Map<String,String> map = new HashMap<>();

    public ShopAdapter(Context context) {
        this.context = context;
    }


    /**
     * 添加数据 并更新显示
     * @param bean
     */
    public void add(ShopBean bean) {
        if (this.list == null) {
            this.list = new ArrayList<>();
        }

        // 遍历商家
        for (ShopBean.DataBean shop : bean.getData()) {
            map.put(shop.getSellerid(),shop.getSellerName());
            // 遍历商品
            for (int i = 0; i < shop.getList().size(); i++) {
                this.list.add(shop.getList().get(i));
            }
        }



        setFirst(this.list);

        notifyDataSetChanged();
    }


    /**
     * 设置数据源, 控制显示商家
     * @param list
     */
    private void setFirst(List<ShopBean.DataBean.ListBean> list){

        if(list.size() > 0){
            list.get(0).setIsFirst(1);
            for(int i=1;i<list.size();i++){
                if(list.get(i).getSellerid() == list.get(i-1).getSellerid()){
                    list.get(i).setIsFirst(2);
                }else{
                    list.get(i).setIsFirst(1);
                    if(list.get(i).isItemSelected()){
                        list.get(i).setShopSelected(list.get(i).isItemSelected());
                    }
                }
            }

        }

    }

    @Override
    public IViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {


        View view = View.inflate(context, R.layout.adapter_layout, null);
        return new IViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final IViewHolder holder, final int position) {


        // 显示商品图片

        if(list.get(position).getIsFirst() == 1){
            //显示商家
            holder.shop_checkbox.setVisibility(View.VISIBLE);
            holder.tvItemShopcartShopname.setVisibility(View.VISIBLE);
            holder.shop_checkbox.setChecked(list.get(position).isShopSelected());

//         显示商家的名称
//            list.get(position).getSellerid() 取到商家的id
//            map.get()取到 商家的名称
            holder.tvItemShopcartShopname.setText(map.get(String.valueOf(list.get(position).getSellerid())));

        } else {
            holder.shop_checkbox.setVisibility(View.GONE);
            holder.tvItemShopcartShopname.setVisibility(View.GONE);
        }


        //控制 商品的  checkbox
        holder.item_checkbox.setChecked(list.get(position).isItemSelected());





        String[] url = list.get(position).getImages().split("\\|");
        ImageLoader.getInstance().displayImage(url[0],holder.item_pic);
        


        holder.item_name.setText(list.get(position).getTitle());
        holder.item_price.setText(list.get(position).getPrice()+"");


        holder.plusViewId.setEditText(list.get(position).getNum());


        // 商家的checkbox
        holder.shop_checkbox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {


                list.get(position).setShopSelected(holder.shop_checkbox.isChecked());

                for(int i=0;i<list.size();i++){
                    if(list.get(position).getSellerid() == list.get(i).getSellerid()){
                        list.get(i).setItemSelected(holder.shop_checkbox.isChecked());
                    }
                }

                notifyDataSetChanged();
                sum(list);

            }
        });

        // 商品的checkbox
        holder.item_checkbox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {


                list.get(position).setItemSelected(holder.item_checkbox.isChecked());


                for(int i=0;i<list.size();i++){
                    for (int j=0;j<list.size();j++){
                        if(list.get(i).getSellerid() == list.get(j).getSellerid() && !list.get(j).isItemSelected()){
                            list.get(i).setShopSelected(false);
                            break;
                        }else {
                            list.get(i).setShopSelected(true);
                        }
                    }
                }

                notifyDataSetChanged();
                sum(list);

            }
        });






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

                list.remove(position);

                setFirst(list);

                notifyDataSetChanged();
                sum(list);

            }
        });




        //加减号
        holder.plusViewId.setListener(new PlusView.ClickListener() {
            @Override
            public void click(int count) {

                list.get(position).setNum(count);
                notifyDataSetChanged();
                sum(list);

            }
        });





    }




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


    /**
     * 计算总价
     * @param list
     */
    private void sum(List<ShopBean.DataBean.ListBean> list){

        int totalNum = 0 ;
        float totalMoney =  0.0f;

        boolean allCheck =true;
        for(int i=0;i<list.size();i++){
            if(list.get(i).isItemSelected()){
                totalNum += list.get(i).getNum() ;
                totalMoney += list.get(i).getNum() * list.get(i).getPrice();
            }else {
                allCheck = false;
            }
        }

        listener.setTotal(totalMoney+"",totalNum+"",allCheck);
    }


    public void selectAll(boolean check){

        for(int i=0;i<list.size();i++){
            list.get(i).setShopSelected(check);
            list.get(i).setItemSelected(check);

        }
        notifyDataSetChanged();

        sum(list);

    }


    static class IViewHolder extends RecyclerView.ViewHolder {


        CheckBox shop_checkbox;

        TextView tvItemShopcartShopname;

        LinearLayout llShopcartHeader;

        CheckBox item_checkbox;

        ImageView item_pic;

        TextView item_price;

        TextView item_name;
        TextView tvItemShopcartClothSize;
       PlusView plusViewId;

        Button item_del;

        IViewHolder(View view) {
            super(view);
            shop_checkbox=view.findViewById(R.id.shop_checkbox);
            tvItemShopcartShopname=view.findViewById(R.id.tv_item_shopcart_shopname);
            llShopcartHeader=  view.findViewById(R.id.ll_shopcart_header);
            item_checkbox= view.findViewById(R.id.item_checkbox);
            item_pic=view.findViewById(R.id.item_pic);
            item_price=view.findViewById(R.id.item_price);
            item_name=view.findViewById(R.id.item_name);
            tvItemShopcartClothSize=view.findViewById(R.id.tv_item_shopcart_cloth_size);
           plusViewId=view.findViewById(R.id.plus_view_id);
            item_del=  view.findViewById(R.id.item_del);
        }
    }


    public UpdateUiListener listener;
    public void setListener(UpdateUiListener listener){
        this.listener = listener;
    }
    interface UpdateUiListener {
        public void setTotal(String total, String num, boolean allCheck);
    }


}

组布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">





    <android.support.v7.widget.RecyclerView
        android:id="@+id/third_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />




    <LinearLayout
        android:layout_weight="0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="#FFFFFF"
        android:gravity="center_vertical"
        android:id="@+id/third_pay_linear"
        >

        <CheckBox
            android:id="@+id/third_allselect"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"

            android:text="全选"

            />

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

            <TextView
                android:id="@+id/third_totalprice"
                android:layout_width="200dp"
                android:layout_height="wrap_content"

                android:text="总价:"

                />

            <TextView

                android:id="@+id/third_totalnum"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"

                android:text="共0件商品"

                />

        </LinearLayout>

        <TextView
            android:id="@+id/third_submit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"

            android:text="去结算"

            android:textColor="#000000"

            />

    </LinearLayout>


</LinearLayout>
适配器布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content"
>

    <LinearLayout
        android:id="@+id/ll_shopcart_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >



        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            >

            <!-- 商店checkbox -->

            <CheckBox
                android:id="@+id/shop_checkbox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"

                />

            <!-- 商店明晨 -->
            <TextView

                android:id="@+id/tv_item_shopcart_shopname"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"

                android:text="宝儿家服装"

                />

        </LinearLayout>

    </LinearLayout>

    <TextView
        android:layout_marginLeft="63dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="111111111111"
        android:id="@+id/item_name"
        />

    <LinearLayout
        android:layout_marginLeft="20dp"
        android:gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <CheckBox

            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/item_checkbox"
            />
        <LinearLayout
            android:padding="10dp"
            android:gravity="center"
            android:layout_width="wrap_content"
            android:orientation="horizontal"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/item_pic"
                android:layout_width="80dp"
                android:layout_height="80dp"
                android:src="@mipmap/ic_launcher"
                />
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                >
                <TextView
                    android:text="10000"
                    android:id="@+id/item_price"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
                <TextView
                    android:text="1000"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/tv_item_shopcart_cloth_size"
                    />
                <aaaaa.myapplication.PlusView
                    android:id="@+id/plus_view_id"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"/>
            </LinearLayout>
            <Button
                android:layout_marginLeft="30dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/item_del"
                android:text="删除"
                />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>
plus_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="match_parent">


    <Button
        android:layout_width="20dp"
        android:layout_height="wrap_content"
        android:id="@+id/revserse"
        android:text="-"
        android:background="#00FFFFFF"/>
    <EditText
        android:inputType="number"
        android:text="1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/content"/>
    <Button
        android:background="#00FFFFFF"
        android:text="+"
        android:id="@+id/add"
        android:layout_width="20dp"
        android:layout_height="wrap_content"
        />
</LinearLayout>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值