现在在为下个项目做准备,之前一直都是使用 MVC模式去开发的,感觉业务什么的还是不够清晰,所以想在下一个项目中使用MVP模式进行开发,对MVP研究了一段时间时候,发表一下自己的见解,也动手写了一个简单的Demo,同时也希望路过的大神可以指点指点。
下面这一段解析是我引用这位大神的,原文链接:http://www.jianshu.com/p/ed2aa9546c2c
但是如果是第一次接触MVP模式或者接触不多的,我建议先不要看这些概念,直接先跳过对这三层的解析,看完我下面的Demo再回过头看会好点。
所谓MVP(Model-View-Presenter)模式。是将APP的结构分为三层:
view - UI显示层
view 层主要负责:
1. 提供UI交互
2. 在presenter的控制下修改UI。
3. 将业务事件交由presenter处理。
注意. View层不存储数据,不与Model层交互。
presenter - 逻辑处理层
presenter 层主要负责:
1. 对UI的各种业务事件进行相应处理。也许是与Model层交互,也许自己进行一些计算,也许控制后台Task,Servic
2. 对各种订阅事件进行响应,修改UI。
3. 临时存储页面相关数据。
注意. Presenter内不出现View引用。
model - 数据层
model层主要负责:
1. 从网络,数据库,文件,传感器,第三方等数据源读写数据。
2. 对外部的数据类型进行解析转换为APP内部数据交由上层处理。
3. 对数据的临时存储,管理,协调上层数据请求。
废话不多说了,直接贴代码展示我的Demo
效果图如下
这种功能是开发中比较常见的。
大概功能:
第一次进入页面先显示加载Progressbar,然后模拟获取数据,获取到的数据加载RecyclerView,完了就隐藏Progressbar,显示内容。
页面增加了下拉刷新、上拉加载更多功能、每一个item的监听。
然后Presenter类就可以定下来了:
如果别人是使用MVP模式开发的话,看Activity或Fragment使用的的Presenter就可以清晰的了解到这个页面的业务功能与逻辑。像看下面这个类就可以知道有什么业务
public interface IBabaPresenter {
/**
* 加载数据
*/
void loadData();
/**
* 下拉刷新数据
*/
void refreshData();
/**
* 上拉加载数据
*/
void loadMoreData();
/**
* 每一条item的点击
*/
void itemClick(Object obj);
}
因为是Demo,我就随便的定了Model的字段
数据的承载体,在这里可以添加数据处理的方法,在这里我就随便写了个方法。比如如果在登录模块,可以做电话号码的验证啊之类的。反正就是与数据有关的处理。
public class BabaModel {
public String name;
/**
* 是不是 巴巴托斯 字段的判断
*/
public boolean isBabaTuoSi(String text) {
if (text.contains("巴巴托斯")) {
return true;
}
return false;
}
}
最后一个就是View类:
处理界面的逻辑。在这个例子,界面要做的事情抽取出来。
public interface IBabaView {
/**
* 拿到数据后,加载RecyclerView
*
* @param mDatas
*/
void loadView(List<BabaModel> mDatas);
/**
* 做下拉刷新
*/
void doRefresh(List<BabaModel> mDatas);
/**
* 做上拉加载
*/
void doLoadMore(List<BabaModel> mDatas);
/**
* 每一个item的点击
*/
void itemClick(Object obj);
/**
* 显示加载进度条
*/
void showLoadingProgressBar();
/**
* 隐藏进度条
*/
void hideLoadingProgressBar();
}
然后就做相关的实现类了。BabaPresenterComplete
在这里我使用Handler做了延迟加载,仿网络访问的效果。
这个类的重点是在构造函数,传入IBabaView 做参数,然后我们就获取IBabaView 的引用进行对UI的处理了,但是这里不会出现对view的引用,像项目中的recyclerView、progressbar不会出现在这里。
/**
* 作者:Leo on 2016/10/14 10:30
* <p/>
* 描述:处理业务事件,切换修改界面UI,要注意的是:这个类里面不会出现对View的引用
*/
public class BabaPresenterComplete implements IBabaPresenter {
private IBabaView iBabaView;
public BabaPresenterComplete(IBabaView iBabaView) {
this.iBabaView = iBabaView;
}
@Override
public void loadData() {
iBabaView.showLoadingProgressBar();
iBabaView.loadView(getDatas());
//给点延时。仿网络加载
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
iBabaView.hideLoadingProgressBar();
}
}, 2000);
}
@Override
public void refreshData() {
//给点延时。仿网络加载
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
iBabaView.doRefresh(getDatas());
}
}, 2000);
}
@Override
public void loadMoreData() {
//给点延时。仿网络加载
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
iBabaView.doLoadMore(getDatas());
}
}, 2000);
}
@Override
public void itemClick(Object obj) {
iBabaView.itemClick(obj);
}
//模拟从网络获取数据
public List<BabaModel> getDatas() {
List<BabaModel> datas = new ArrayList<>();
for (int i = 0; i < 8; i++) {
BabaModel babaModel = new BabaModel();
if (i % 2 == 0) {
babaModel.name = "巴巴托斯" + new Random().nextInt(100);
} else {
babaModel.name = "独角兽" + new Random().nextInt(100);
}
datas.add(babaModel);
}
return datas;
}
}
然后展示的是Activity
创建BabaPresenterComplete 的对象,在这里具体实现IBabaView,View 的引用全部都留在Activity中。但是调用会放在BabaPresenterComplete 中调用。
public class ListActivity extends AppCompatActivity implements IBabaView, OnMyItemClickListener {
private Toolbar toolbar;
private XRecyclerView recyclerView;
private LinearLayout llytProgress;
private BabaAdapter babaAdapter;
private BabaPresenterComplete babaPresenterComplete;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("初加载、刷新、加载更多、点击");
llytProgress = (LinearLayout) findViewById(R.id.progressBar);
recyclerView = (XRecyclerView) findViewById(R.id.recyclerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setLoadingMoreEnabled(true);
recyclerView.setPullRefreshEnabled(true);
//看这里
babaPresenterComplete = new BabaPresenterComplete(this);
babaPresenterComplete.loadData();
recyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {
@Override
public void onRefresh() {
babaPresenterComplete.refreshData();
}
@Override
public void onLoadMore() {
babaPresenterComplete.loadMoreData();
}
});
}
@Override
public void loadView(List<BabaModel> mDatas) {
babaAdapter = new BabaAdapter(this, mDatas);
recyclerView.setAdapter(babaAdapter);
babaAdapter.setOnMyItemClickListener(this);
}
@Override
public void doRefresh(List<BabaModel> mDatas) {
if (babaAdapter != null) {
babaAdapter.addRefreshDatas(mDatas);
}
recyclerView.refreshComplete();
}
@Override
public void doLoadMore(List<BabaModel> mDatas) {
if (babaAdapter != null) {
babaAdapter.addLoadMoreDatas(mDatas);
//隐藏进度条
recyclerView.loadMoreComplete();
}
}
@Override
public void itemClick(Object obj) {
if (((BabaModel) obj).isBabaTuoSi(((BabaModel) obj).name))
Toast.makeText(this, "点击了 巴巴托斯", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "点击的不是巴巴托斯,会被打的", Toast.LENGTH_SHORT).show();
}
@Override
public void showLoadingProgressBar() {
recyclerView.setVisibility(View.GONE);
llytProgress.setVisibility(View.VISIBLE);
}
@Override
public void hideLoadingProgressBar() {
llytProgress.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
}
@Override
public void onItemClick(Object obj, int position) {
babaPresenterComplete.itemClick(obj);
}
}
看到这里你会发现使用MVP模式开发,项目的业务逻辑会很清晰,如果去修改相关的功能,你会很快的找到去修改。
并且如果增加了需求,像如果当前页面增加一个重刷页面的按钮,不想修改BabaPresenterComplete 的话,也可以多写一个IReloadPresenter,里面就是包含reload的方法,因为java支持多实现;
public interface IBabaReloadView {
/**
* 重新加载
*/
void reloadView();
}
public interface IBabaReloadPresenter {
/**
* 所有重新加载
*/
void reloadAll();
}
注
总结一下,其实对MVP现在还不是很熟悉,但是写这个Demo算是为下一个项目做准备吧。可能等我使用MVP模式去做完下一个项目的话,会对MVP有更深入的认识,学无止境啊。
也希望路过的大神或者对MVP有见解的,指点一下。小六不胜感激。