MVP的一点理解

版权声明:转载请注明出处 https://blog.csdn.net/dl10210950/article/details/62425255

学习MVP已经有一段时间了,看了很多资料,也写了好几个demo,前段时间一直都在做项目,没时间总结一下,趁着这段时间没有那么忙了,把我学习的一些理解记录下来

总结起来就这张图
mvp图解

举个我自己理解的例子
M和V在闹离婚,都不愿意和对方去沟通,这是后P就出现了,负责M和V的沟通工作…
V把离婚条件告诉P,P接到条件后就去问M,M考虑好条件告诉(接口回调给)P,P在去告诉V,V在做相应的处理.总结起来就是这个流程

自古文字留不住,总是代码得人心!下面开始撸代码

demo模拟刷新请求网络,显示请求的数据,看看目录
这里写图片描述

1,首先要展示数据,是不是要一个JavaBean,那就建一个

package com.duanlian.mvpdemo.model;

import java.util.List;

/**
 * 数据的javaBean
 */

public class DataBean {


    private ShowapiResBodyBean showapi_res_body;
    private int showapi_res_code;
    private String showapi_res_error;

    public ShowapiResBodyBean getShowapi_res_body() {
        return showapi_res_body;
    }

    public void setShowapi_res_body(ShowapiResBodyBean showapi_res_body) {
        this.showapi_res_body = showapi_res_body;
    }

    public int getShowapi_res_code() {
        return showapi_res_code;
    }

    public void setShowapi_res_code(int showapi_res_code) {
        this.showapi_res_code = showapi_res_code;
    }

    public String getShowapi_res_error() {
        return showapi_res_error;
    }

    public void setShowapi_res_error(String showapi_res_error) {
        this.showapi_res_error = showapi_res_error;
    }

    public static class ShowapiResBodyBean {
        /**
         * allNum : 29951
         * allPages : 1498
         * currentPage : 1
         * maxResult : 20
         * ret_code : 0
         */

        private int allNum;
        private int allPages;
        private int currentPage;
        private int maxResult;
        private int ret_code;
        private List<ContentlistBean> contentlist;

        public int getAllNum() {
            return allNum;
        }

        public void setAllNum(int allNum) {
            this.allNum = allNum;
        }

        public int getAllPages() {
            return allPages;
        }

        public void setAllPages(int allPages) {
            this.allPages = allPages;
        }

        public int getCurrentPage() {
            return currentPage;
        }

        public void setCurrentPage(int currentPage) {
            this.currentPage = currentPage;
        }

        public int getMaxResult() {
            return maxResult;
        }

        public void setMaxResult(int maxResult) {
            this.maxResult = maxResult;
        }

        public int getRet_code() {
            return ret_code;
        }

        public void setRet_code(int ret_code) {
            this.ret_code = ret_code;
        }

        public List<ContentlistBean> getContentlist() {
            return contentlist;
        }

        public void setContentlist(List<ContentlistBean> contentlist) {
            this.contentlist = contentlist;
        }

        public static class ContentlistBean {
            /**
             * ct : 2017-03-13 02:06:36.050
             * id : 58c58e2c6e360f5dbfe2772f
             * img : http://sc1.hao123img.com/data/3933e840a88aaee4a102dbc7987ab67b_0
             * title : 跳高都能这么妖娆
             * type : 2
             */

            private String ct;
            private String id;
            private String img;
            private String title;
            private int type;

            public String getCt() {
                return ct;
            }

            public void setCt(String ct) {
                this.ct = ct;
            }

            public String getId() {
                return id;
            }

            public void setId(String id) {
                this.id = id;
            }

            public String getImg() {
                return img;
            }

            public void setImg(String img) {
                this.img = img;
            }

            public String getTitle() {
                return title;
            }

            public void setTitle(String title) {
                this.title = title;
            }

            public int getType() {
                return type;
            }

            public void setType(int type) {
                this.type = type;
            }
        }
    }
}

为啥要先建个bean呢,因为这个bean要在MVP3个中间传输的

2,创建一个请求Model数据成功失败的监听接口,这个接口是要回调到Presenter的,
创建一个Presenter收到请求成功或者失败后把结果传递给View层去做相应的处理的接口,
我这边是写在一个接口里(之所以这么写,因为别人都这么写,苦逼的我认为别人写的代码都很牛逼)

package com.duanlian.mvpdemo;

import com.duanlian.mvpdemo.model.DataBean;

/**
 * view和model的接口
 */

public interface Contract {
    //View的接口
    interface View {
        //成功后的回调去设置数据
        void setInfo(DataBean dataBean);

        //失败后的回调,去显示失败相关
        void setError();
    }

    //Model的接口
    interface Model {
        //请求数据成功后的回调
        void onSuccess(DataBean dataBean);

        //请求数据失败后的回调
        void onError();
    }
}

3,创建一个请求数据的interface(也可以不创建,之所以创建时因为别人都创建了)参数1和2都是用来拼接地址的,参数3是用来返回请求结果的

package com.duanlian.mvpdemo.model;

import com.duanlian.mvpdemo.Contract;

/**
 * 请求数据方法的接口
 * 不用这个接口也行
 */

public interface GetData {
    //传入一个请求数据的地址,一个请求的页数,一个请求结果的监听,成功失败都返回一个结果
    void getData(String url, int page, Contract.Model model);
}

4,创建一个请求数据的类,实现刚才创建的接口

package com.duanlian.mvpdemo.model;

import com.duanlian.mvpdemo.Contract;
import com.google.gson.Gson;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;

import okhttp3.Call;

/**
 * 用来请求和返回数据的类
 */

public class GetDataModel implements GetData{
    @Override
    public void getData(String url, int page, final Contract.Model model) {
        OkHttpUtils.get()
                .url(url + page)
                .build()
                .execute(new StringCallback() {
                    @Override
                    public void onError(Call call, Exception e, int id) {
                        //把请求失败返回去
                        model.onError();
                    }

                    @Override
                    public void onResponse(String response, int id) {
                        Gson gson = new Gson();
                        DataBean dataBean = gson.fromJson(response, DataBean.class);
                        //请求成功把bean返回过去
                        model.onSuccess(dataBean);
                    }
                });
    }
}

5,接下来就是presenter了,注释很清楚了,就不啰嗦了

package com.duanlian.mvpdemo.presenter;

import com.duanlian.mvpdemo.Contract;
import com.duanlian.mvpdemo.model.DataBean;
import com.duanlian.mvpdemo.model.GetData;
import com.duanlian.mvpdemo.model.GetDataModel;

/**
 * view和model的中间枢纽
 */

public class MyPresenter implements Contract.Model, GetData {
    //既然Presenter是连接View和model的桥梁,所以他既有View的引用也有Model的引用
    Contract.View mView;
    GetDataModel mModel;

    //构造方法把View传递过来
    public MyPresenter(Contract.View view) {
        this.mView = view;
        mModel = new GetDataModel();

    }

    @Override
    public void onSuccess(DataBean dataBean) {
        //如果model里面请求数据成功就返回到这里,然后吧数据传递过去,通知View去展示相关数据
        mView.setInfo(dataBean);
    }

    @Override
    public void onError() {
        //如果数据请求失败的话就通知View去显示失败后的相关
        mView.setError();
    }

    @Override
    public void getData(String url, int page, Contract.Model model) {
        //通知model去请求数据,请求结果会返回到这里的onSuccess()和onError()
        mModel.getData(url, page, this);
    }
}

6,作为View层最轻松了,就是通知Presenter去请求网络,然后就是等待数据的返回了

package com.duanlian.mvpdemo;

import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
import android.widget.Toast;

import com.duanlian.mvpdemo.adapter.ListViewAdapter;
import com.duanlian.mvpdemo.model.DataBean;
import com.duanlian.mvpdemo.presenter.MyPresenter;

public class MainActivity extends AppCompatActivity implements Contract.View {
    private ListView mListView;
    private SwipeRefreshLayout mRefreshLayout;
    private ListViewAdapter mAdapter;
    private MyPresenter mPresenter;
    private int page = 1;
    private String url;


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

    private void initView() {
        mListView = (ListView) findViewById(R.id.listview);
        mRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.refresh);
        //实例化Presenter,把View传递过去
        mPresenter = new MyPresenter(this);
        url = "http://route.showapi.com/341-2?maxResult=20&showapi_appid=28968&showapi_sign=4e30b3520be34fe09846cc2c3a3c203f&page=";
//        mPresenter.getData(url, page, null);
        mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //通知presenter去请求网络
                mPresenter.getData(url, page, null);
            }
        });

    }

    @Override
    public void setInfo(DataBean dataBean) {
        if (dataBean != null) {
            mRefreshLayout.setRefreshing(false);
            mAdapter = new ListViewAdapter(this, dataBean);
            mListView.setAdapter(mAdapter);
        }
    }

    @Override
    public void setError() {
        mRefreshLayout.setRefreshing(false);
        Toast.makeText(this, "失败了", Toast.LENGTH_SHORT).show();
    }
}

View层最重要的是把View的实例通过presenter的构造方法传递过去,然后就是等待presenter的返回了

我的理解大概就这么多了,后面有新的理解持续更新,
demo运行效果
这里写图片描述

demo地址:点击下载

猜你喜欢

转载自blog.csdn.net/dl10210950/article/details/62425255