Mvp+OkHttp+购物车

本文深入解析了MVC架构模式,包括Model(模型)、View(视图)和Controller(控制器)的实现原理。通过具体示例,展示了如何使用MVC模式进行软件设计,以实现更好的代码分离和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MyCallBack

public interface MyCallBack {
    void setData(Data data);
    void setError(String error);

}

Model

public interface Model {
    void getData(String url, MyCallBack callBack);
}
public class ModelImp implements Model{
    private MyCallBack callBack;
    private Handler mp  = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what==0){
                String s= (String) msg.obj;
                Gson gson=new Gson();
                Data data = gson.fromJson(s, Data.class);
                callBack.setData(data);
            }
        }
    };
    @Override
    public void getData(final String url, final MyCallBack callBack) {
        this.callBack = callBack;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String jsonStr = OkHttpUtils.getInctance().get(url);
                    mp.sendMessage(mp.obtainMessage(0,jsonStr));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

Presenter

public interface IPresenter {
    void startRequest(String url);
}
public class IPresenterImp implements IPresenter{
    private ModelImp modelImp;
    private IView iView;

    public IPresenterImp(IView iView) {
        this.iView = iView;
        modelImp = new ModelImp();
    }

    @Override
    public void startRequest(String url) {
        modelImp.getData(url, new MyCallBack() {
            @Override
            public void setData(Data data) {

                iView.getSuccess(data);
            }

            @Override
            public void setError(String error) {
                iView.getError(error);
            }
        });
    }
}

IView

public interface IView {
    void getSuccess(Data data);
    void getError(String error);
}

自定义控件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="30dp"
    android:layout_gravity="center_vertical"
    android:layout_marginLeft="10dp"
    android:background="#99000000"
    android:gravity="center_vertical"
    android:padding="2dp">

    <TextView
        android:id="@+id/delete_tv"
        android:layout_width="20dp"
        android:layout_height="50dp"
        android:background="#ffffff"
        android:gravity="center"
        android:text="-"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/product_number_tv"
        android:layout_width="30dp"
        android:layout_height="50dp"
        android:layout_marginLeft="2dp"
        android:layout_weight="1"
        android:background="#ffffff"
        android:gravity="center"
        android:text="1" />

    <TextView
        android:id="@+id/add_tv"
        android:layout_width="20dp"
        android:layout_height="50dp"
        android:layout_marginLeft="2dp"
        android:background="#ffffff"
        android:gravity="center"
        android:text="+"
        android:textSize="16sp" />

</LinearLayout>
public class ZiDingYiActivity extends LinearLayout implements View.OnClickListener {

    private TextView mAdd;
    private TextView mDelete;
    private TextView mNumber;
    //商品数量
    private int mCount;

    public ZiDingYiActivity(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.zidingyi, this);
        initViews();
    }

    private void initViews() {
        mAdd = findViewById(R.id.add_tv);
        mDelete = findViewById(R.id.delete_tv);
        mNumber = findViewById(R.id.product_number_tv);
        mAdd.setOnClickListener(this);
        mDelete.setOnClickListener(this);
    }

    //先给初始值赋值
    public void setNumber(int number) {
        this.mCount = number;
        mNumber.setText(number + "");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.delete_tv:
                if (mCount > 0) {
                    mCount--;
                    mNumber.setText(mCount + "");
                    if (mCountChange!=null){
                        mCountChange.setCount(mCount);
                    }
                }else {
                    Toast.makeText(getContext(), "商品已售空", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.add_tv:
                mCount++;
                mNumber.setText(mCount + "");
                if (mCountChange!=null){
                    mCountChange.setCount(mCount);
                }
                break;
        }
    }

    public interface OnCountChange {
        void setCount(int count);
    }

    private OnCountChange mCountChange;

    public void setOnChange(OnCountChange countChange) {
        this.mCountChange = countChange;
    }
}

Activity

public class Main2Activity extends AppCompatActivity implements IView2 {

    private String mUrl = "http://www.wanandroid.com/tools/mockapi/6523/restaurant-list";
    private ArrayList<User.DataBean> lists =  new ArrayList<>();
    private ExpandableListView expand_view;
    private TextView go_to_js;
    private TextView all_price;
    private CheckBox check_all;

    private IPresenterImp2 iPresenterImp2;
    private ErJiAdapter adapter;

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


        try {
            iPresenterImp2 = new IPresenterImp2(this);
            iPresenterImp2.startRequest(mUrl);
        } catch (IOException e) {
            e.printStackTrace();
        }

        adapter = new ErJiAdapter(lists,this);
        expand_view.setAdapter(adapter);

        adapter.setCallBack(new ErJiAdapter.AdapterCallback() {
            @Override
            public void setCroupCheck(int groupPosition) {
                boolean childAllCheck = adapter.isChildAllCheck(groupPosition);
                adapter.childAllCheck(groupPosition, !childAllCheck);
                adapter.notifyDataSetChanged();
                diaoyong();
            }

            @Override
            public void setChildCheck(int groupPosition, int childPosition) {
                boolean childChecked = adapter.isChildChecked(groupPosition, childPosition);
                adapter.setChildChecked(groupPosition,childPosition,!childChecked);
                adapter.notifyDataSetChanged();
                diaoyong();
            }

            @Override
            public void setNumber(int groupPosition, int childPosition, int number) {
                adapter.setShangPingNumber(groupPosition,childPosition,number);
                adapter.notifyDataSetChanged();
                diaoyong();
            }
        });

        check_all.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                 boolean allGoods = adapter.isAllGoods();
                 adapter.setAllGoodsIsChecked(!allGoods);
                 adapter.notifyDataSetChanged();
                 diaoyong();
            }
        });
    }

    private void initView() {
        check_all = findViewById(R.id.Check_All);
        all_price = findViewById(R.id.All_Price);
        go_to_js = findViewById(R.id.Go_To_JS);
        expand_view = findViewById(R.id.Expand_View);
        expand_view.setGroupIndicator(null);
    }

    @Override
    public void getSuccess(User data) {
        lists.addAll(data.getData());
        adapter.notifyDataSetChanged();
    }

    @Override
    public void getError(String error) {
        Toast.makeText(this, "失败", Toast.LENGTH_SHORT).show();
    }

    private void  diaoyong(){
         boolean allGoods = adapter.isAllGoods();
         check_all.setChecked(allGoods);
         int allGoodsNumber = adapter.getAllGoodsNumber();
         float allGoodsPrice = adapter.getAllGoodsPrice();
         all_price.setText("价格:" + allGoodsPrice);
         go_to_js.setText("去结算(" + allGoodsNumber + ")");
    }
}

Adapter

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener{
    private ArrayList<Data.DataBean> lists;
    private Context context;

    public MyAdapter(ArrayList<Data.DataBean> lista, FragmentActivity contexta) {
        this.lists = lista;
        this.context = contexta;
    }

    @NonNull
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {

        View v = LayoutInflater.from(context).inflate(R.layout.item,viewGroup,false);

        ViewHolder viewHolder = new ViewHolder(v);
        v.setOnClickListener(this);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyAdapter.ViewHolder viewHolder, int i) {
        ViewGroup.LayoutParams params = viewHolder.itemView.getLayoutParams();
        Random random = new Random();
        int gao = random.nextInt(100)+200;
        params.height = gao;
        viewHolder.itemView.setLayoutParams(params);


        Glide.with(context).load(lists.get(i).getPic_url()).into(viewHolder.img);
        viewHolder.text1.setText(lists.get(i).getName()+"");
        viewHolder.text2.setText(lists.get(i).getBulletin()+"");
        viewHolder.text3.setText(lists.get(i).getAverage_price_tip()+"");

        viewHolder.itemView.setTag(i);
    }

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

    public interface ItemClick {
        void setOnItemClick(View view, int position);
    }

    private ItemClick mItemClick;

    public void setOnClickListener(ItemClick itemClick) {
        this.mItemClick = itemClick;
    }

    @Override
    public void onClick(View v) {
        if (mItemClick != null) {
            mItemClick.setOnItemClick(v, (int) v.getTag());
        }
    }
    public class ViewHolder extends RecyclerView.ViewHolder {

        private  ImageView img;
        private  TextView text1;
        private  TextView text2;
        private  TextView text3;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            img = itemView.findViewById(R.id.img);
            text1 = itemView.findViewById(R.id.text1);
            text2 = itemView.findViewById(R.id.text2);
            text3 = itemView.findViewById(R.id.text3);
        }
    }
}

erjiAdapter

public class ErJiAdapter extends BaseExpandableListAdapter {
    private ArrayList<User.DataBean> lists= new ArrayList<>();
    private Context context;

    public ErJiAdapter(ArrayList<User.DataBean> listsa, Context contexta) {
        this.lists = listsa;
        this.context = contexta;
    }

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

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

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

    @Override
    public Object 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 View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        GroupHolder groupHolder = null;
        if (convertView == null){
            groupHolder = new GroupHolder();
            convertView = View.inflate(context,R.layout.item2,null);
            groupHolder.GroupCheckBox = convertView.findViewById(R.id.group_cb);
            groupHolder.GroupTextView = convertView.findViewById(R.id.group_tv);
            convertView.setTag(groupHolder);
        }else{
            groupHolder = (GroupHolder) convertView.getTag();
        }
        User.DataBean dataBean = lists.get(groupPosition);
        groupHolder.GroupTextView.setText(dataBean.getName()+"");

        boolean childAllCheck = isChildAllCheck(groupPosition);
        groupHolder.GroupCheckBox.setChecked(childAllCheck);
        groupHolder.GroupCheckBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (adapterCallback!=null){
                    adapterCallback.setCroupCheck(groupPosition);
                }
            }
        });

        return convertView;
    }

    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ChildHolder childHolder = null;
        if (convertView == null){
            childHolder = new ChildHolder();
            convertView = View.inflate(context,R.layout.item3,null);
            childHolder.ChildCheckBox = convertView.findViewById(R.id.child_cb);
            childHolder.ChildImage = convertView.findViewById(R.id.child_img);
            childHolder.ChildTextView1 = convertView.findViewById(R.id.child_tv1);
            childHolder.ChildTextView2 = convertView.findViewById(R.id.child_tv2);
            //查找自定义控件
            childHolder.ZiDingYi = convertView.findViewById(R.id.zidingyi);
            convertView.setTag(childHolder);
        }else{
          childHolder = (ChildHolder) convertView.getTag();
        }
        User.DataBean.SpusBean spusBean = lists.get(groupPosition).getSpus().get(childPosition);
        Glide.with(context).load(spusBean.getPic_url()).into(childHolder.ChildImage);
        childHolder.ChildTextView1.setText(spusBean.getName()+"");
        childHolder.ChildTextView2.setText("¥"+spusBean.getSkus().get(0).getPrice());
        childHolder.ChildCheckBox.setChecked(spusBean.isChildChecked());
        //自定义控件赋值
        childHolder.ZiDingYi.setNumber(spusBean.getPraise_num());
        childHolder.ChildCheckBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (adapterCallback!=null){
                    adapterCallback.setChildCheck(groupPosition,childPosition);
                }
            }
        });
        childHolder.ZiDingYi.setOnChange(new ZiDingYiActivity.OnCountChange() {
            @Override
            public void setCount(int count) {
                if (adapterCallback!=null){
                    adapterCallback.setNumber(groupPosition,childPosition,count);
                }
            }
        });
        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return false;
    }
    class GroupHolder{
        CheckBox GroupCheckBox;
        TextView GroupTextView;
    }
    class ChildHolder{
        CheckBox ChildCheckBox;
        ImageView ChildImage;
        TextView ChildTextView1;
        TextView ChildTextView2;
        ZiDingYiActivity ZiDingYi;
    }
    //111111111111111111111111点击group的CheckBox让所有child选中
    public void childAllCheck(int groupPosition, boolean isCheck) {
        User.DataBean dataBean = lists.get(groupPosition);
        List<User.DataBean.SpusBean> spus = dataBean.getSpus();
        for (int i = 0; i < spus.size(); i++) {
            User.DataBean.SpusBean bean = spus.get(i);
            bean.setChildChecked(isCheck);
        }
    }
    //11111111111111111111111用来判断小组是否全被选中
    public boolean isChildAllCheck(int groupPosition) {
        boolean boo = true;
        User.DataBean dataBean = lists.get(groupPosition);
        List<User.DataBean.SpusBean> spus = dataBean.getSpus();
        for (int i = 0; i < spus.size(); i++) {
            User.DataBean.SpusBean bean = spus.get(i);
            //只要有一个没有被选中 点这个CheckBox就是全选的功能
            if (!bean.isChildChecked()) {
                return false;
            }
        }
        return boo;
    }

    //2222222222222222222222因为咱们底部视图有个一全选和反选
    public boolean isAllGoods() {
        boolean boo = true;
        for (int i = 0; i < lists.size(); i++) {
            User.DataBean dataBean = lists.get(i);
            for (int j = 0; j < dataBean.getSpus().size(); j++) {
                User.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
                if (!spusBean.isChildChecked()) {
                    boo = false;
                }
            }
        }
        return boo;
    }

    //222222222222222222222全选反选功能
    public void setAllGoodsIsChecked(boolean isAllCheck) {
        for (int i = 0; i < lists.size(); i++) {
            User.DataBean dataBean = lists.get(i);
            for (int j = 0; j < dataBean.getSpus().size(); j++) {
                User.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
                spusBean.setChildChecked(isAllCheck);
            }
        }
    }
    //22222222222222222222点击child给他进行赋值
    public void setChildChecked(int groupPositon, int childPositon, boolean isCheckBox) {
        User.DataBean.SpusBean spusBean = lists.get(groupPositon).getSpus().get(childPositon);
        spusBean.setChildChecked(isCheckBox);
    }
    //22222222222222222222查看当前这个商品有没有被选中
    public boolean isChildChecked(int groupPositon, int childPositon) {
        User.DataBean.SpusBean spusBean = lists.get(groupPositon).getSpus().get(childPositon);
        if (spusBean.isChildChecked()) {
            return true;
        }
        return false;
    }

    //333333333333333333333333333计算所有商品的价格
    public float getAllGoodsPrice() {
        float allPrice = 0;
        for (int i = 0; i < lists.size(); i++) {
            User.DataBean dataBean = lists.get(i);
            for (int j = 0; j < dataBean.getSpus().size(); j++) {
                User.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
                if (spusBean.isChildChecked()){
                    allPrice = allPrice + spusBean.getPraise_num() * Float.parseFloat(spusBean.getSkus().get(0).getPrice());
                }
            }
        }
        return allPrice;
    }
    //333333333333333333333333333计算所有商品的数量
    public int getAllGoodsNumber() {
        int allNumber = 0;
        for (int i = 0; i < lists.size(); i++) {
            User.DataBean dataBean = lists.get(i);
            for (int j = 0; j < dataBean.getSpus().size(); j++) {
                User.DataBean.SpusBean spusBean = dataBean.getSpus().get(j);
                if (spusBean.isChildChecked()){
                    allNumber = allNumber + spusBean.getPraise_num();
                }
            }
        }
        return allNumber;
    }

    //333333333333333333333333333给商品数量进行赋值

    public void setShangPingNumber(int groupPosition, int childPosition, int number) {
        User.DataBean.SpusBean spusBean = lists.get(groupPosition).getSpus().get(childPosition);
        spusBean.setPraise_num(number);
    }

    //自定义一个接口
    public interface  AdapterCallback{
        void setCroupCheck(int groupPosition);

        void setChildCheck(int groupPosition,int childPosition);

        void setNumber(int groupPosition,int childPosition,int number);
    }

    private AdapterCallback adapterCallback;

    public void setCallBack(AdapterCallback adapterCallback){
        this.adapterCallback = adapterCallback;
        }

}

OkHttp

public class OkHttpUtils {
    public static OkHttpClient okHttpClient;

    private OkHttpUtils() {
        HttpLoggingInterceptor interceptor=new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(10,TimeUnit.SECONDS)
                .writeTimeout(10,TimeUnit.SECONDS)
                .readTimeout(10,TimeUnit.SECONDS)
                .addInterceptor(interceptor)
                .build();
    }

    public static OkHttpUtils getInctance(){
        return OkViewHolder.UTIL;
    }

    static class OkViewHolder{
        public static OkHttpUtils UTIL = new OkHttpUtils();
    }

    public static String get(String mPath) throws IOException {
        Request request = new Request.Builder().url(mPath).build();
        Response response = okHttpClient.newCall(request).execute();
        return response.body().string();
    }
}

防止内存泄漏

  //防止内存泄漏
    public void onDetatch() {
        if (modelImp2 != null) {
            modelImp2 = null;
        }
        if (iView2 != null) {
            iView2 = null;
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值