【Android学习】两种MVP模式的学习(一):谷歌例子的简单学习

来源:互联网 发布:vagaa哇嘎画时代 mac 编辑:程序博客网 时间:2024/05/26 02:21

关于MVP的介绍网上有很多,身为搬运工的我直接搬来百度百科的,其实想来大家也都知道的。


MVP:

mvp的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理。

MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交

互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。


在学习MVP模式的时候,最近比较火的是谷歌的例子:

https://github.com/googlesamples/android-architecture

结构很清晰,用一个契约类将View,Presenter的接口写在里面,这样可以清晰的知道有哪些功能,界面有哪些会有变化,数据有哪些需要处理。 


在Presenter创建时传入到View,同时将自身注入到View中,甚是巧妙。


来看一个小李子:


这是我模仿 掌上英雄联盟做的界面 ,除去 ViewPager中的内容,这个界面有两个地方需要获取数据。

一、轮播图。

二、Tab标签以及 “赛事”和“视频” 这俩悬浮页。

根据Fiddler听到的数据来看 ,轮播图是一个请求,Tab和悬浮页是一个请求。



所以基本步骤就是 ,定义设计Model,BaseView ,BasePresenter。


这里的Model比较简单,看一下就过去了:

model接口:

public interface LoLItemModel {    Observable<LoLBean> getLoLNewsData(String id, int page, String plat, int version);    Observable<LoLBean> getLoLBanner( String plat, int version);    Observable<List<LoLTypeBean>> getLoLType(String plat, int version);}

model实现类:

public class LoLItemModelImpl implements LoLItemModel {    @Override    public Observable<LoLBean> getLoLNewsData(String id, int page,String plat, int version) {        LoLService service = NetWork.getInstance().create(LoLService.class);        return service.getNewsLoL(id, page, plat, version);    }    @Override    public Observable<LoLBean> getLoLBanner(String plat, int version) {        LoLService service = NetWork.getInstance().create(LoLService.class);        return service.getLoLBanner(plat, version);    }    @Override    public Observable<List<LoLTypeBean>> getLoLType(String plat, int version) {        LoLService service = NetWork.getInstance().create(LoLService.class);        return service.getLoLType(plat, version);    }}

 Model 是在Presenter中进行实例化操作的。


接着来看BaseView,BasePresenter:


public interface IBaseView<T> {    void setPresenter(T presenter);}


public interface IBasePresenter {        void start();        void destroy();}


BasePresenter里面的方法看实际而定,我可能需要初始化一些东西,定义了start(),因为使用RxJava,要考虑生命周期,所以定义一个destroy,在View结束时解绑。


然后就是契约类,这个界面 需要和数据进行交互的 只有设置轮播图,tab页。

所以就暂时先定下两个方法。


public class LoLMainContract {    public interface View extends IBaseView<Presenter> {        void initBanner(List<LoLBean.ListBean> bannerUrls);        void initTabs(List<LoLTypeBean> listbean);    }    public interface Presenter extends IBasePresenter {        void getBannersData();        void getTabsData();    }}


实现Presenter:

在构造函数中 获取View同时将自身传入 View中。

public class LoLMainPresenter implements LoLMainContract.Presenter {    private LoLMainContract.View mView;    LoLItemModelImpl lolIml;    Subscription getBannerSPN;    Subscription getTabSPN;    public LoLMainPresenter(LoLMainContract.View mView) {        this.mView = mView;        this.mView.setPresenter(this);        lolIml = new LoLItemModelImpl();    }    @Override    public void getBannersData() {        getBannerSPN = RxManager.getInstance().doSubscribe(lolIml.getLoLBanner("android", 9705), new Subscriber<LoLBean>() {            @Override            public void onCompleted() {            }            @Override            public void onError(Throwable e) {            }            @Override            public void onNext(LoLBean loLTypeBeen) {                mView.initBanner(loLTypeBeen.getList());            }        });    }    @Override    public void getTabsData() {        getTabSPN = RxManager.getInstance().doSubscribe(lolIml.getLoLType("android", 9705), new Subscriber<List<LoLTypeBean>>() {            @Override            public void onCompleted() {            }            @Override            public void onError(Throwable e) {            }            @Override            public void onNext(List<LoLTypeBean> loLTypeBeen) {                mView.initTabs(loLTypeBeen);            }        });    }    @Override    public void start() {    }    @Override    public void destroy() {        if (getBannerSPN != null)            getBannerSPN.unsubscribe();        if (getTabSPN != null)            getTabSPN.unsubscribe();    }}


在View生命周期结束的时候对观察者解绑。


然后就是实现View。

这里是Fragment 做View ,Activity统筹管理View


public class LoLMainFragment extends BaseFragment implements LoLMainContract.View{  }

我们的fragment实现契约类中Presenter的View接口,

声明Presenter并在实现View的方法中赋值:

 private LoLMainContract.Presenter mPresenter;    @Override    public void setPresenter(LoLMainContract.Presenter presenter) {        this.mPresenter = presenter;    }


获取数据 :

 mPresenter.getBannersData(); mPresenter.getTabsData();

获取之后会调用View的方法 将返回的数据 在View中显示。



都实现之后就是  最后创建Fragment

 lolMainFragment = new LoLMainFragment();


我们在Fragment的onCreate中创建Presenter的实例,并将自身传入:


 new LoLMainPresenter(this);


这样一个基本的MVP模式就出来了。

这只是练手用的,熟悉MVP构建方法流程。但是我们不能为了架构了使用架构,视具体情况而定。

页面功能多,逻辑复杂,那就得好好思量思量要怎么去实现能让层次清晰,维护方便。

总之,开心就好。


最近学到的还有一种MVP实现方式,挺好的,下篇来学习。

Mosby:https://github.com/sockeqwe/mosby 




0 0
原创粉丝点击