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

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

作者: 莫离境 | 来源:发表于2016-09-25 20:23 被阅读459次

关于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

相关文章

网友评论

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

      本文链接:https://www.haomeiwen.com/subject/itbfyttx.html