在《Android源码设计模式解析》 中的最后一章中讲述了关于Android中MVP架构的实现,在以前的项目中多数是以 MVC +MVP的实现方法,一旦涉及到多人的开发,因为大家的思路与想法的不同,整个项目完成之后较难维护。在网上搜索了一些现有的AndroidMVP框架,要么就是Presenter类过于复杂,要么就是View和Model之间没有做到完全的分离,所以就有了自己去做一个MVP的框架的想法。(对MVP模式还不是很理解的可以去:http://blog.csdn.net/u011068996/article/details/51144502).
参考:Android App的设计架构:MVC,MVP,MVVM与架构经验谈:http://www.tianmaying.com/tutorial/AndroidMVC
MVPExtend
MVPExtend存在主要为实现Android项目中的视图与逻辑的分离,即在Activity、Fragment只作为View存在不应该包含业务和处理逻辑(或者只应该有简单的逻辑存在)。Presenter的作用就是为了分割View和Model的的关联,Presenter中通常持有View和Model的引用,通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑。
MVPExtend的作用主要是减轻View(Activity、Fragment)层的压力,从而增加项目的可读性使项目更能适应变化。
Activity 专注于 View的操作,只有它自己应该知道界面是什么样子的,Model专注于处理数据,也只有他自己数据是什么样子的,Presenter作为连接View和Model的中介,从Model中获取数据,从View中获取控件,然后把他们组合在一起。
就好像,房东、中介、房客,房东把要求提交给中介,同一个房东可能会找到多个中介,中介根据房东的要求去找到房客,多个中介会找到多个房客,房东与房客并不能直接接触,完全通过中介在中间去做交流,房东与房客的信息只有中介是最清楚的,他们只能通过中介去获取对方的信息。
OK 说了那么多 下面上代码:
整个框架的结构设计:
区分Model、Presenter、View。共提供三个抽象类一个接口,所有实现MVPExtend的项目分别需要集成对应的抽象类,获取实现对应的接口。
View:
View区分了Activity和Fragment:
public abstract class MVPExtendActivity extends AppCompatActivity{
/**
* 保存所有findViewById的View集合
*/
private Map<Integer,View> mViews;
@Nullable
@Override
public View findViewById(@IdRes int id) {
View view = super.findViewById(id);
mViews.put(id,view);
return view;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
mViews = new HashMap<>();
super.onCreate(savedInstanceState);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mViews != null){
mViews.clear();
mViews = null;
}
}
/**
* 通过ID 获取视图
*/
public View getView(int id){
View view = mViews.get(id);
if (view == null){
view = findViewById(id);
if (view != null){
mViews.put(id,view);
}
}
return view;
};
}
/**
* Created by Sunday on 16/4/28.
*/
public abstract class MVPExtendFragment extends Fragment{
private static final int VIEW = 0x216;
private Map<Integer,View> mViews;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
mViews = new HashMap<>();
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
mViews.put(VIEW,view);
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onDestroy() {
super.onDestroy();
if (mViews != null){
mViews.clear();
mViews = null;
}
}
/**
* 通过ID 获取视图
*/
public View getView(int id){
View view = mViews.get(id);
if (view == null){
view = mViews.get(VIEW).findViewById(id);
if (view != null){
mViews.put(id,view);
}
}
return view;
};
}
创建了一个Map集合用于保存所有的View视图,重写了FindViewById的方法,吧加载过得视图放入Map集合之中,对外提供一个getView方法,用于在Presenter中通过Id去获取对应的View。
Presenter:
/**
* Created by Sunday on 16/4/28.
*/
public abstract class MVPExtendPresente<M,V>{
protected V mMainView;
public MVPExtendPresente(V mainView){
this.mMainView = mainView;
}
/**
* 设置数据到视图
* @param m
*/
protected abstract void setDataToView(M m);
}
Presenter中提供了两个泛型,分别对应Model和View,提供一个setDataToView的方法,用于设置数据。
Model
/**
* Created by Sunday on 16/4/28.
*/
public interface IMVPExtendModel {
/**
* 简单获取数据的回调接口
* 提供获取数据成功和获取数据失败的回调方法
*/
interface OnRequestDataListener<M>{
/**
* 获取数据成功
*/
void onSuccess(M m);
/**
* 获取数据失败
*/
void onFailure(String error);
}
/**
* 获取数据
*/
void onRequestData(OnRequestDataListener onLoadDataListener);
}
Model类中提供了一个接口和一个内部接口用于请求数据和处理返回的数据。
GitHub地址:https://github.com/lgd8981289/MVPExtend
具体使用方式请点击:http://download.csdn.net/detail/u011068996/9506371