MVP简单入门(附视频资料)

来源:互联网 发布:淘宝教育上直通车 编辑:程序博客网 时间:2024/06/18 05:02

为什么使用MVP?

一般在Activity中既要写关于界面渲染 用户处理的代码 又要处理关于网络 数据库的请求,如果一个界面的功能复杂,那么就很容易在Activity中造成代码混乱,引用MVP 可以使代码结构逻辑更加清晰,业务逻辑与界面的剥离,解耦。

MVP实际上分为三个概念

  • View 对应于Activity、Fragment,负责View的绘制以及与用户交互
  • Model 业务逻辑和实体模型
  • Presenter 负责完成View于Model间的交互 让View与Model之间完全剥离,通过Presenter作为媒介,使两者起交互作用。

举个例子:

加载一串数据显示在TextView中,Model就是负责去加载这个数据,View就是显示TextView,如何把数据显示到TextView中呢? 就是通过Presenter去调用Model加载数据,然后通过接口返回给View。

根据这上面这个例子,按照流程编写成一个简单demo(点击按钮 模拟一个网络请求 在请求的过程中展示加载框 并在数据加载完成后隐藏加载框和展示网络请求结果):

1.既然MVC是由3个模块组成,这里首先为MainActivity定义IMainView接口规范

public interface IMainView {}public class MainActivity extends AppCompatActivity implements IMainView {}

2.定义布局界面

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="asyncRequest"        android:text="模拟异步请求" />    <TextView        android:id="@+id/result_tv"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></LinearLayout>

3.初始化布局控件

public class MainActivity extends AppCompatActivity implements IMainView {    private TextView mResultTv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mResultTv =(TextView) findViewById(R.id.result_tv);    }    //按钮点击事件    public void asyncRequest(View v){    }}

4.点击按钮执行asyncRequest方法。接着由View层告诉Presenter层处理网络请求,这里先创建Presenter层,由于上面Presenter层与View层交流,所以这里Presenter层必须持有View层。代码如下。

public interface IShowPresenter {    //定义模拟的网络请求    public void doNetworkRequest();}public class ShowPresenterImpl implements IShowPresenter{    private IMainView mMainView;    public ShowPresenterImpl(IMainView mainView) {        mMainView=mainView;     }    @Override    public void doNetworkRequest() {    }}

5.在View层中,onCreate()方法创建Presenter层,当点击按钮,通知Presenter层做网络请求。

public class MainActivity extends AppCompatActivity implements IMainView {    ...    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ...        //初始化Presenter层        mPresenter=new ShowPresenterImpl(this);    }    public void asyncRequest(View v){        //开始网络请求        mPresenter.doNetworkRequest();    }    //显示对话框    @Override    public void showProgress(String s) {        mDialog=new ProgressDialog(this);        mDialog.setMessage(s);        mDialog.show();    }}

public class ShowPresenterImpl implements IShowPresenter{    ...    @Override    public void doNetworkRequest() {        //1.展示数据加载对话框        mMainView.showProgress("模拟数据正在加载中...");        //2.做网络请求  TODO        ...    }}

6.实际上,Presenter层只是做为一个中间件,真正的网络请求是Model层,所以这里首先创建Model层,并定义网络请求的规范。

public interface IShowModel {    void doNetworkRequest();}public class ShowModelImpl implements IShowModel {    private IShowListener mListener;    private Handler mHandler=new Handler(){        @Override        public void handleMessage(Message msg) {            //数据如何返回呢?      (String) msg.obj            //TODO         }    };    @Override    public void doNetworkRequest() {        new Thread(){            @Override            public void run() {                SystemClock.sleep(3000);                String mockData="模拟请求的数据完毕。。。";                mHandler.obtainMessage(0,mockData).sendToTarget();            }        }.start();    }}

6.上面的Model层提供了一个网络请求的方法doNetworkRequest(),该方法由Presenter层调用。

public class ShowPresenterImpl implements IShowPresenter,IShowModel.IShowListener{    ...    private IShowModel mShowModel;    public ShowPresenterImpl(IMainView mainView) {        ...        mShowModel=new ShowModelImpl(this);    }    @Override    public void doNetworkRequest() {        //1.展示数据加载对话框        ...        //2.做网络请求        mShowModel.doNetworkRequest();    }}

7.数据在Model层请求完毕后,需要将数据告诉Presenter层先,这里定义了一个回调接口。

public interface IShowModel {    ...    public static interface IShowListener{        void onNetworkRequestFinish(String result);    }}

8.Presenter是被通知的对象,所以也是回调接口的继承者,继承了回调接口后还要通知Model层。
public class ShowPresenterImpl implements IShowPresenter,IShowModel.IShowListener{

    public ShowPresenterImpl(IMainView mainView) {        ...        //将回调接口告诉Model层        mShowModel=new ShowModelImpl(this);    }    //实现回调接口的方法    @Override    public void onNetworkRequestFinish(String result) {        ...    }}

9.Model层数据请求结束后 通过回调接口告诉Presenter层。

public class ShowModelImpl implements IShowModel {    private IShowListener mListener;    private Handler mHandler=new Handler(){        @Override        public void handleMessage(Message msg) {            //数据如何返回呢?            if (mListener!=null){                mListener.onNetworkRequestFinish((String) msg.obj);            }        }    };    public ShowModelImpl(IShowListener mListener) {        this.mListener = mListener;    }    ...}

10.Presenter接收到网络请求的接口 告诉View层隐藏记载框并且修改显示的UI。

public class ShowPresenterImpl implements IShowPresenter,IShowModel.IShowListener{    ...    @Override    public void onNetworkRequestFinish(String result) {        //3.修改UI        mMainView.resetResultTv(result);        //4.隐藏数据加载的对话框        mMainView.hideProgress();    }}public class MainActivity extends AppCompatActivity implements IMainView {    ...    @Override    public void hideProgress() {        if (mDialog!=null){            mDialog.dismiss();        }    }    @Override    public void resetResultTv(String result) {        mResultTv.setText(result);    }}

示例结果:

总结

感觉上单纯为了简单的实现,而去写这么多的代码,但是逻辑和结构上是更加地清晰了,业务和界面实现的方式完全剥离开。在实际的项目中这种做法更利于后期的开发和维护。

视频资料: http://pan.baidu.com/s/1gfgHH0R

0 0
原创粉丝点击