MVP模式入门
概述
应用软件程序开发过程中,大都会涉及到UI界面、数据、业务逻辑处理。当业务逻辑非常复杂的时候为了能更清晰的开发维护程序代码,需要对程序进行框架设计,最早的MVC模式便应运而生.后来也被应用于Android应用程序开发中。
MVP可以看作是MVC的一种升级。在MVC中Activity其实是View层级,但是通常在使用中Activity即是View也是Controller,并没有将View层和Controller层进行分离,耦合度非常高,非常不利于项目的管理。这时候MVP就应运而生了。
MVC架构
M : 业务层和模型层,相当与javabean和我们的业务请求代码 model层主要负责: · 从网络,数据库,文件,传感器,第三方等数据源读写数据。 · 对外部的数据类型进行解析转换为APP内部数据交由上层处理。 · 对数据的临时存储,管理,协调上层数据请求。 V : 视图层,对应Android的layout.xml布局文件 C : 控制层,对应于Activity中对于UI 的各种操作
看起来MVC架构很清晰,但是实际的开发中,请求的业务代码往往被丢到了Activity里面,大家都知道layout.xml的布局文件只能提供默认的UI设置,所以开发中视图层的变化也被丢到了Activity里面,再加上Activity本身承担着控制层的责任。所以Activity达成了MVC集合的成就,最终我们的Activity就变得越来越难看,从几百行变成了几千行。维护的成本也越来越高
新的MVP架构
M : 还是业务层和模型层 V : 视图层的责任由Activity来担当 P : 新成员Prensenter 用来代理 C(control) 控制层,是View和Model的中间“桥梁”,负责View和Model间的交互
MVP与MVC最大的不同,其实是Activity职责的变化,由原来的C (控制层) 变成了 V(视图层),不再管控制层的问题,只管如何去显示。控制层的角色就由我们的新人 Presenter来担当,这种架构就解决了Activity过度耦合控制层和视图层的问题。
实例
第一步View层
[java]/**
* 定义UI视图逻辑
*/
public interface ICheapView {
void setListViewAdapter(ReadNewsAdapter adpater);
void showToastMessage(String message);
void setBannerLayoutData(List<AdsBean> list);
}
public class CheapFragment extends BaseMvpFragment<ICheapView, CheapPresenter> implements ICheapView, View.OnClickListener {
private EditText mSearchKey;
private ListView mListView;
private FrameLayout mListHeadView;
private BannerLayout mBannerLayout;
public static CheapFragment newInstance() {
CheapFragment fragment = new CheapFragment();
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mListHeadView = (FrameLayout) inflater.inflate(fragment_cheap_banner_layout, null);
return inflater.inflate(R.layout.fragment_cheap_layout, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mSearchKey = (EditText) getView().findViewById(R.id.com_search_edit);
mBannerLayout = (BannerLayout) mListHeadView.findViewById(R.id.banner);
mListView = (ListView) getView().findViewById(R.id.cheap_listview);
mListView.addHeaderView(mListHeadView);
mSearchKey.setOnClickListener(this);
mPresenter.setListViewAdapter();
mPresenter.setListBannerViewData();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.com_search_edit:
getActivity().onSearchRequested();
break;
}
}
@Override
public CheapPresenter initPresenter() {
return new CheapPresenter(getActivity());
}
@Override
public void setListViewAdapter(ReadNewsAdapter adpater) {
mListView.setAdapter(adpater);
}
@Override
public void showToastMessage(String message) {
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
}
@Override
public void setBannerLayoutData(List<AdsBean> urls) {
List<String> list = new ArrayList<>();
for (AdsBean ads : urls) {
list.add(ads.getImgsrc());
}
mBannerLayout.setViewUrls(list);
//添加监听事件
mBannerLayout.setOnBannerItemClickListener(new BannerLayout.OnBannerItemClickListener() {
@Override
public void onItemClick(int position) {
showToastMessage(String.valueOf(position));
}
});
}
}[/java]
第二步Presenter层
[java]/**
* 定义业务逻辑
*/
public interface ICheapPresenter {
void setListViewAdapter();
void setListBannerViewData();
}
public class CheapPresenter extends BasePresenter<ICheapView> implements ICheapPresenter{
private ICheapModel mCheapModel;
private ReadNewsAdapter mReadNewsAdapter;
public CheapPresenter(Context context) {
mCheapModel = new CheapModel();
mReadNewsAdapter = new ReadNewsAdapter(context);
}
@Override
public void setListViewAdapter() {
mView.setListViewAdapter(mReadNewsAdapter);
}
@Override
public void setListBannerViewData() {
mCheapModel.setListAndAdsData(new CallbackListener<NewsTextBean>() {
@Override
public void onSuccess(NewsTextBean data) {
List<NewsTextItemBean> newsTextItemBeanList = data.getT1348647909107();
mReadNewsAdapter.addDatas(0,newsTextItemBeanList);
List<AdsBean> adsLists = newsTextItemBeanList.get(0).getAds();
mView.setBannerLayoutData(adsLists);
}
@Override
public void onFailure(String message) {
mView.showToastMessage(message);
}
});
}
}
[/java]
第三步实现Mode层
[java]public interface ICheapModel {
void setListAndAdsData(final CallbackListener<NewsTextBean> listener);
}
public class CheapModel implements ICheapModel {
@Override
public void setListAndAdsData(final CallbackListener<NewsTextBean> listener) {
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://c.m.163.com/")
.build();
RetrofitCall call = retrofit.create(RetrofitCall.class);
Call<NewsTextBean> mCall = call.getNewsText();
mCall.enqueue(new Callback<NewsTextBean>() {
@Override
public void onResponse(Call<NewsTextBean> call, Response<NewsTextBean> response) {
NewsTextBean newsTextBean = response.body();
listener.onSuccess(newsTextBean);
}
@Override
public void onFailure(Call<NewsTextBean> call, Throwable t) {
listener.onFailure(t.getMessage());
}
});
}
}[/java]
BaseMvpFragment主要封装对Presenter的实例化.
BasePresenter实现在Presenter中持有View的引用.
[java]
public abstract class BasePresenter<T> {
/*这个基类的Presenter 主要的作用就是将当前Presenter持有的view 在合适的时候给清除掉*/
public T mView;
public void attach(T mView) {
this.mView = mView;
}
public void dettach() {
mView = null;
}
}[/java]
[java]
public abstract class BaseMvpFragment<V, T extends BasePresenter<V>> extends Fragment {
/*定义一个Presenter 用于解绑持有的View
*
* 在onAttach进行初始化Presenter的操作
* 在onCreate中进行绑定
* 在onDestroy 中进行解绑
*
**/
public T mPresenter;
@Override
public void onAttach(Context context) {
super.onAttach(context);
mPresenter = initPresenter();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPresenter.attach((V) this);
}
@Override
public void onDestroy() {
super.onDestroy();
mPresenter.dettach();
}
/* 这里是适配为不同的View 装载不同Presenter*/
public abstract T initPresenter();
}[/java]
参考学习
Android单排上王者系列之Android MVP解析实践
转载请注明来源:MVP模式入门




























