Mvp开发模式
废话不多说 ,我将分三篇或者四篇 进行说明
第一篇 Mvp+Retrofit2
第二篇 Mvp+RxJava+Retrofit2
第三篇 Mvp+RxJava+Dagger2+Retrofit2
下面 第一篇开始,在这里说明一点 为了让大家看得清晰,我在这里就除了网络请求其它就不分包了,方便大家看目录结构
先看目录结构
在这里说明一下 首字母是“I”的都是接口
继续
Mvp 模式的精髓就是面向接口编程,为什么这么说呢,其实,笔者认为代码可维护性,可拓展性的精髓就是面向接口编程。就比如,一个接口有N个实现类,突然来需求了,要你在这个接口里面加一个方法,那你直接在接口里面加就得了,然后他的实现类里面都实现一下。这样你就不会漏掉任何一个,提高了维护效率是肯定的,同时,你也少写了很多代码不是吗,所以说,Mvp就采用了这种思路。
介绍一下
M即Model : 顾名思义,就是模型,用于存放数据
V即View: 就是视图,里面写一下 用于UI操作的一些方法
P即Presenter 主持人,里面持有 View和Model 主要任务是做一些业务逻辑,联系二者,将数据和UI进行关联。
ValueCallBack:回调接口,只有两种可能,成功或者失败,加一个泛型T,用于拓展它的受用面。
public interface ValueCallBack<T> {
void onSuccess(T t);
void onFailed(String errCode);
}
IView 视图接口,用于UI操作
public interface IZhihuView {
void showToast(String toastStr);
void refreshView();
void setOnEmpty();
}
Entity(GsonFormat自动生成)
public class Entity {
/**
* date : 20170626
* stories : [{"images":["https://pic1.zhimg.com/v2-b022395e73c72c5377b974c9452b2248.jpg"],"type":0,"id":9494287,"ga_prefix":"062618","title":"- 今天心情不好,不去运动了\r\n- 你哪天心情好过?"},{"images":["https://pic1.zhimg.com/v2-193096b3e4a32ceeca18e2c7f4dbca84.jpg"],"type":0,"id":9494901,"ga_prefix":"062617","title":"建筑中一个失败的细节,可能会变成「杀人凶器」"},{"images":["https://pic3.zhimg.com/v2-45ad4cd45c5a8ad2c165f6e48437e59a.jpg"],"type":0,"id":9491337,"ga_prefix":"062616","title":"将来我不会打自己的孩子,因为我知道还有更好的教育方式"},{"images":["https://pic1.zhimg.com/v2-9c7eb03dae75d83454571572b05b0c1c.jpg"],"type":0,"id":9494049,"ga_prefix":"062615","title":"与其说四大衰落了,不如说是审计行业开始回归常态"},{"images":["https://pic3.zhimg.com/v2-c2597b3c4f43297457a032976ec41b7a.jpg"],"type":0,"id":9491311,"ga_prefix":"062614","title":"只想安静地放空表情,怎么一不小心就向领导摆了张臭脸?"},{"images":["https://pic3.zhimg.com/v2-d984c2f6dd9a325ea4a559cf07516ff2.jpg"],"type":0,"id":9492269,"ga_prefix":"062613","title":"《帝国时代》20 年:你可还记得大明湖畔的伐木工?"},{"images":["https://pic3.zhimg.com/v2-b967db3abbe9399f0f363b0b1f7c52f6.jpg"],"type":0,"id":9486441,"ga_prefix":"062612","title":"大误 · 朕这皇帝我不当了"},{"images":["https://pic4.zhimg.com/v2-15f38eb7bb3137c75bd7dc8a3264cd0b.jpg"],"type":0,"id":9493628,"ga_prefix":"062611","title":"贴吧「关停并转」,高层人事动荡,陆奇和百度寻找下一个千亿美元计划"},{"images":["https://pic2.zhimg.com/v2-8aa443402ef9d4ca7c21d3784b1fdc41.jpg"],"type":0,"id":9493089,"ga_prefix":"062610","title":"作为一个辩论新手,如何自我提高?"},{"images":["https://pic2.zhimg.com/v2-4cc947cfa7d8e47dd44b5eeea757cc29.jpg"],"type":0,"id":9492517,"ga_prefix":"062609","title":"既然吃下去都是热量,我们为什么不把吃饭改成吃糖?"},{"images":["https://pic3.zhimg.com/v2-03d63fd3c401f0671fd601af4b891bbe.jpg"],"type":0,"id":9492978,"ga_prefix":"062608","title":"员工下班就准点走,真是没有「事业心」啊"},{"images":["https://pic4.zhimg.com/v2-d6818fb887fb602034d9d1512d48b21f.jpg"],"type":0,"id":9493083,"ga_prefix":"062607","title":"这些被遗忘的编程语言,还在诉说他们的故事"},{"images":["https://pic2.zhimg.com/v2-a632e6650b2f16e8224f5aee23df3471.jpg"],"type":0,"id":9492565,"ga_prefix":"062607","title":"一人一票选 CEO 的公司能赚到钱吗?"},{"images":["https://pic1.zhimg.com/v2-a23785b2003cdfe2192bdb5afa72fcc0.jpg"],"type":0,"id":9492696,"ga_prefix":"062607","title":"老人摔倒要不要扶?冷静,先听医生怎么说"},{"images":["https://pic3.zhimg.com/v2-9ba48b44a7ba09ce5984009e8b10b62e.jpg"],"type":0,"id":9492380,"ga_prefix":"062606","title":"瞎扯 · 如何正确地吐槽"}]
* top_stories : [{"image":"https://pic1.zhimg.com/v2-582f85f6b7deaaf9aaadb53fbf1fb3a8.jpg","type":0,"id":9493628,"ga_prefix":"062611","title":"贴吧「关停并转」,高层人事动荡,陆奇和百度寻找下一个千亿美元计划"},{"image":"https://pic1.zhimg.com/v2-18287777ea60f73f7e00de07ea3bb354.jpg","type":0,"id":9492696,"ga_prefix":"062607","title":"老人摔倒要不要扶?冷静,先听医生怎么说"},{"image":"https://pic2.zhimg.com/v2-dcaac62fda5695da379d289088bb50cd.jpg","type":0,"id":9491805,"ga_prefix":"062510","title":"传说中最美的荧光海,其实在国内也有"},{"image":"https://pic2.zhimg.com/v2-b86e151e46bc321f4abf34caef8b4445.jpg","type":0,"id":9491681,"ga_prefix":"062507","title":"他们回家了吗?他们相会了吗?只是我们永远都不知道了"},{"image":"https://pic2.zhimg.com/v2-dbb5f84d70b41b06359e6cb9cef38ab5.jpg","type":0,"id":9491009,"ga_prefix":"062509","title":"作为医生,我亲身参与过汶川、玉树和雅安地震灾后救援"}]
*/
private String date;
private List<StoriesBean> stories;
private List<TopStoriesBean> top_stories;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public List<StoriesBean> getStories() {
return stories;
}
public void setStories(List<StoriesBean> stories) {
this.stories = stories;
}
public List<TopStoriesBean> getTop_stories() {
return top_stories;
}
public void setTop_stories(List<TopStoriesBean> top_stories) {
this.top_stories = top_stories;
}
public static class StoriesBean {
/**
* images : ["https://pic1.zhimg.com/v2-b022395e73c72c5377b974c9452b2248.jpg"]
* type : 0
* id : 9494287
* ga_prefix : 062618
* title : - 今天心情不好,不去运动了
- 你哪天心情好过?
*/
private int type;
private int id;
private String ga_prefix;
private String title;
private List<String> images;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getGa_prefix() {
return ga_prefix;
}
public void setGa_prefix(String ga_prefix) {
this.ga_prefix = ga_prefix;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<String> getImages() {
return images;
}
public void setImages(List<String> images) {
this.images = images;
}
}
public static class TopStoriesBean {
/**
* image : https://pic1.zhimg.com/v2-582f85f6b7deaaf9aaadb53fbf1fb3a8.jpg
* type : 0
* id : 9493628
* ga_prefix : 062611
* title : 贴吧「关停并转」,高层人事动荡,陆奇和百度寻找下一个千亿美元计划
*/
private String image;
private int type;
private int id;
private String ga_prefix;
private String title;
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getGa_prefix() {
return ga_prefix;
}
public void setGa_prefix(String ga_prefix) {
this.ga_prefix = ga_prefix;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
}
IZhihuMode(不理解的话,照着敲10遍,下一篇我在讲)
public interface IZhihuMode {
void getZhihuData(ValueCallBack<List<Entity.StoriesBean>> valueCallBack);
List<Entity.StoriesBean> returnDataToAdapter();
}
ZhihuMode 具体的数据操作类
public class ZhihuMode implements IZhihuMode {
private List<Entity.StoriesBean> listData;
public ZhihuMode() {
listData=new ArrayList<>();
}
@Override
public void getZhihuData(final ValueCallBack<List<Entity.StoriesBean>> valueCallBack) {
Call<Entity> zhihuData = RetrofitManger.getInstance().getZhihuData();
zhihuData.enqueue(new Callback<Entity>() {
@Override
public void onResponse(Call<Entity> call, Response<Entity> response) {
List<Entity.StoriesBean> stories = response.body().getStories();
valueCallBack.onSuccess(stories);
}
@Override
public void onFailure(Call<Entity> call, Throwable t) {
valueCallBack.onFailed(t.getMessage());
}
});
}
@Override
public List<Entity.StoriesBean> returnDataToAdapter() {
return listData;
}
}
BasePresenter这里为什么不用接口呢,因为接口里面的方法没有方法体,而抽象类就没有那么多限制,操作更灵活,拓展性更强。
public abstract class BasePresenter<T extends BaseActivity> {
abstract void initData();
}
IZhihuPresenter
public interface IZhihuPresenter {
List<Entity.StoriesBean> getAdapterData();
}
ZhihuPresenter 报错不要管
public class ZhihuPresenter extends BasePresenter<ZhihuActivity> implements IZhihuPresenter {
private IZhihuView view;
private IZhihuMode mode;
public ZhihuPresenter(IZhihuView view) {
this.view = view;
mode=new ZhihuMode();
}
@Override
void initData() {
mode.getZhihuData(new ValueCallBack<List<Entity.StoriesBean>>() {
@Override
public void onSuccess(List<Entity.StoriesBean> storiesBeen) {
mode.returnDataToAdapter().addAll(storiesBeen);
view.refreshView();
}
@Override
public void onFailed(String errCode) {
view.showToast(errCode);
view.setOnEmpty();
}
});
}
@Override
public List<Entity.StoriesBean> getAdapterData() {
return mode.returnDataToAdapter();
}
}
BaseActivity 这里有点高能,泛型是T 继承 BasePresenter 然后具体的Activity继承BaseActivity ,在前面又可知,具体的Presenter继承BasePresenter,所以,具体的Activity就可以通过继承baseActicity里面的泛型,来引用具体的Presenter,我说得不太好,语言表达能力有限,不懂的话,就一个字 ,敲!!!
public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity {
public T basePresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayout());
initView();
basePresenter=initPresenter();
onPrepare();
}
protected abstract void onPrepare();
protected abstract T initPresenter();
protected abstract void initView();
protected abstract int getLayout();
}
ZhihuActivity
public class ZhihuActivity extends BaseActivity<ZhihuPresenter> implements IZhihuView {
private ListView listView;
private MyListAdapter adapter;
@Override
protected void onPrepare() {
basePresenter.initData();
adapter=new MyListAdapter(this,basePresenter.getAdapterData());
listView.setAdapter(adapter);
}
@Override
protected ZhihuPresenter initPresenter() {
return new ZhihuPresenter(this);
}
@Override
protected void initView() {
listView= (ListView) findViewById(R.id.list001);
}
@Override
protected int getLayout() {
return R.layout.activity_zhihu;
}
@Override
public void showToast(String toastStr) {
Toast.makeText(this, toastStr, Toast.LENGTH_SHORT).show();
}
@Override
public void refreshView() {
adapter.notifyDataSetChanged();
}
@Override
public void setOnEmpty() {
}
}
至此,别忘了加上网络请求,XML 自己写吧 ,就俩也不难,
是不是感觉梦梦的,没关系,蒙着蒙着就会了。