关于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中显示。
都实现之后就是 将V,P实例出来。
可以将方法放到 Fragment的 create中 。最好封装起来
new LoLMainPresenter(this);
这样一个基本的MVP模式就出来了。
这只是练手用的,熟悉MVP构建方法流程。但是我们不能为了架构了使用架构,视具体情况而定。
页面功能多,逻辑复杂,那就得好好思量思量要怎么去实现能让层次清晰,维护方便。
总之,开心就好。
最近学到的还有一种MVP实现方式,挺好的,下篇来学习。
Mosby:https://github.com/sockeqwe/mosby