使用Mobsy进行MVP实战
MVP介绍
- M:Model,需要显示的数据,以及获取和保存数据的相关逻辑
- V:View,显示数据的页面或空间,并接受用户的交互
- P:Presenter,处于M和V中间,是对产品交互的抽象。决定M由哪个V显示,V的动作会引起哪些数据的变化。
如下为典型的MVP工作流程
需要注意的点:
- Presenter不应该直接处理View的事件
- View只应向Presenter传递消息,并接受Presenter的命令
- Activity和Fragment是View的一部分,一般可用于处理用户事件
- Presenter和Model应该是纯Java代码,而且可以独立的运行单元测试
Mosby介绍
gradle依赖
|
|
MvpView和MvpPresenter
- MvpView是个空接口。在实际使用时,会扩展这个接口来定义一系列的View的方法
- MvpView会依附或脱离于MvpPresenter。库中定义好的一些MvpView使用代理模式实现了依附和脱离的逻辑。
- MvpPresenter通过软引用访问View,从而避免内存泄漏
|
|
通过MvpLceFragment学习使用MVP
LCE就是Loading-Content-Error,代表了一个典型的移动互联网应用的页面。
- 显示LoadingView,并在后台获取数据
- 如果获取成功,显示获取的到数据
- 如果失败,显示一个错误的提示View
先看看MvpLceView
|
|
实现MvpLceView的控件或页面一定要包含至少3个View,他们的id分别为R.id.loadingView
,R.id.contentView
和 R.id.errorView
,因此我们使用如下的xml为Fragment布局。
库工程中的MvpLceFragment
和MvpLceActivity
已经实现了MvpLceView
的三个方法showLoading
,showContent
和showError
,
|
|
这个页面中将显示一个从网络获取的国家列表,先看看Presenter的代码。这里通过CountriesAsyncLoader获取国家列表,并通过setData和showContent让View显示这些国家信息。当然还获取前显示Loading,获取失败后显示Error。
|
|
最后是MvpLceFragment,注意其中的createPresenter
是所有的MvpView都需要实现的方法,用于创建和MvpView关联的Presenter,另一个setData
两个方法是MvpLceFragment中没有实现的方法,因为只有实现的时候才知道最终的Model,已经如何显示这个Model。
另一个要注意的是MvpLceFragment的四个范型,依次是:显示内容的AndroidView,需要显示的内容Model,MvpView,MvpPresenter。
|
|
实战——封装一个LceListView
这部分代码可参考代码,只用关注mvplist包下的相关代码即可。
这个页面的View结构和之前的MvpLceFrgment类似,并通过修改Adapter给RecycleView的末尾增加了一个LoadMoreView。将这类业务的下拉刷新,上拉加载更多,以及错误处理都抽象出来。实现列表时,剩下的逻辑主要包括
- Model:获取的数据,以及从数据中获取每个列表项展示需要的数据列表
- Presenter:刷新和加载更多时,分别调用Model的获取数据方法
- View:根据数据决定ViewHolder的类型,以及ViewHolder的实现
如何使用,可以参考mvplist.sample包的内容
基类LecListView的方案
LecListView包含了一个LoadMoreView,LoadMoreView也符合Mvp架构。
我们先看看LoadMoreView的实现。
LoadMoreView
- 没有Model:这里的数据只包括一个状态,因此没有对应的Model类
- LoadMoreView
- 提供一个
setState(int state)
方法,供Presenter更新状态 - 加载更多失败的情况下,点击View会请求Presenter更改状态到Loading
- 提供一个
- LoadMorePresenter
- 通过
setLoadMoreState(int state)
改变View的状况 - 通过接口
LoadMoreListener#onLoadMore
通知LceListViewPresenter加载更多数据
- 通过
LecListView
- IListModel:在
LceListView
中,Model应实现IListModel,从而提供一个在RecycleView中显示的数据列表。
```Java
public interface IListModel<M> {
List<M> getData();
}
```
- LceListView
- 实现了
MvpLceView
的五个方法,和在列表底部添加数据的addData
方法 - 监听RecyclerView的滚动,通知Presenter改变加载更多的状态
- 使用LceListAdapter为RecyclerView底部增加了LoadMoreView
- 实现了
- LceListPresenter实现ILceListPresenter
- 在refreshData时,通知LceListView显示Loading
- 包含一个LoadMorePresenter来实现ILoadMorePresenter的接口
- 在LoadMoreView附着在窗口时,调用
LceListPresenter#setLoadMorePresenter