什么是MVP?
相信也不用我过多赘述了,MVP现在也不是什么新鲜的东西了,说白了就是:
MODEL - VIEW - PRESENTER
附上一张经典截图:
image.png
(为什么V与P是双向箭头?答案在后方)
按照国际惯例,我现在应该写一腿和MVC模式的对比,优越性之类的。偏偏我不喜欢这样,因为已经有太多这类博客了,有兴趣的可以看看其他的博客。在这里我只讲解一些重要的东西。
废话不说,show me the code !!!
(ps:网上的实例全是登录。。。也不知道是谁抄谁的,真无语!!!)
这里我使用了GankIO的一个api,嘻嘻。。。
代码结构
image.png这里可以看出:
Model就是实体类,还有就是如何获取数据的一些类和方法(联网、数据库......)
View就是activity/fragment之类的界面显示逻辑
Presenter就是从model中取数据,为view提供数据的中间枢纽
完整代码我就不贴了,理解万岁!!!(demo链接在后面)
在这里我们主要看看P层:
MeiziPresenter
public interface MeiziPresenter {
void loadImagelList();
}
MeiziPresenterImpl
public class MeiziPresenterImpl implements MeiziPresenter, OnLoadListener {
private MeiziView meiziView;
private MeiziModel meiziModel;
public MeiziPresenterImpl(MeiziView meiziView) {
this.meiziView = meiziView;
meiziModel = new MeiziModelImpl();
}
@Override
public void loadImagelList() {
meiziView.showProgress();
meiziModel.onLoadImage(this);
}
@Override
public void onSuccess(List<Meizi.ResultsBean> list) {
System.out.println("onSuccess-------------------");
if (null != list){
meiziView.showImages(list);
meiziView.hideProgress();
}
}
@Override
public void onFailed(Exception e, String s) {
meiziView.hideProgress();
meiziView.showFailed(e,s);
}
}
其实,我们可以大胆地把这里引用的view想形成一个特别的activity,拿到数据就到具体的显示逻辑,这样可以方便理解(个人认为)
上面我们可以看到MeiziPresenterImpl实现了对应的presenter接口,同时也持有对view和model的引用,这就是它的关键之处。我们可以看到preenter主要是提供数据的,那么数据从哪里来呢?接下来,继续看M层:
MeiziModel
public interface MeiziModel {
void onLoadImage(OnLoadListener listener);
}
MeiziModelImpl
public class MeiziModelImpl implements MeiziModel {
@Override
public void onLoadImage(final OnLoadListener listener) {
String url = "http://gank.io/api/random/data/福利/10";
OkHttpClient client = new OkHttpClient();
final Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
listener.onFailed(e,"load failed,,,");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String result = response.body().string();
System.out.println("success get ");
List<Meizi.ResultsBean> list
= new Gson().fromJson(result,Meizi.class).getResults();
listener.onSuccess(list);
}
});
}
}
没错!!!mode就是数据的生产方!!!在这里我举个具体例子:
如果将activity比作我们,presenter比作商店老板,model比作厂家
那么他们的关系也就不言而喻了:
我们最实在,只要卖到商品就行了,不用管商品是哪里来的,这就是view的显示;
而老板在为我们提供商品之前得进货嘛,所以他要去厂家,厂家有货他就拿,不用管怎么生产;
再来就是厂家了,厂家也不会平白无故生产那么多垃圾,有客户需求它才生产(也就是请求数据),这就是model的工作
这么一来他们的工作就很清楚了!
最后是activity'的显示逻辑以及对应的activity:
public interface MeiziView {
void showImages(List<Meizi.ResultsBean> list);
void showFailed(Exception e,String s);
void showProgress();
void hideProgress();
}
public class MainActivity extends AppCompatActivity implements MeiziView, SwipeRefreshLayout.OnRefreshListener {
private MeiziAdapter adapter;
private List<Meizi.ResultsBean> data;
private RecyclerView recyclerView;
private SwipeRefreshLayout refreshLayout;
private MeiziPresenter presenter;
private TestAdapter testadapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
refreshLayout = (SwipeRefreshLayout) findViewById(R.id.refresh);
presenter = new MeiziPresenterImpl(this);
refreshLayout.setOnRefreshListener(this);
recyclerView.setLayoutManager(new GridLayoutManager(this,2));
adapter = new MeiziAdapter(getApplicationContext());
// testadapter = new TestAdapter(getApplicationContext());
recyclerView.setAdapter(adapter);
onRefresh();
}
@Override
public void showImages(List<Meizi.ResultsBean> list) {
if (data == null) {
data = new ArrayList<>();
}
System.out.println("=========list size is " + list.size());
data.addAll(list);
adapter.setList(data);
runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
}
});
}
@Override
public void showFailed(Exception e, String s) {
Toast.makeText(this, "" + s, Toast.LENGTH_SHORT).show();
}
@Override
public void showProgress() {
refreshLayout.setRefreshing(true);
}
@Override
public void hideProgress() {
runOnUiThread(new Runnable() {
@Override
public void run() {
refreshLayout.setRefreshing(false);
}
});
}
@Override
public void onRefresh() {
if (data != null){
data.clear();
}
presenter.loadImagelList();
}
}
运行截图:
meizi.gif结局撒花
MVP模式咋一看就是太多类了,其实例子太小根本体现不出优势。但是,一屋不扫何以扫天下?
我认为MVP最优秀的地方就是解耦方面,这正是我们需要的,再来就是多多练习了,我也是刚刚接触不久,快毕业了(失业)了,哈哈。
以上纯属个人见解,有很多不足,但是毕竟是自己敲过的东西,多多少少还是有点收获!我们学习跟多的是学习一种思维方式,而不是全部照搬,只有理解了才会有所变通,不然换一个角度就懵逼了。
demo源码
网友评论