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层
/** * 定义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)); } }); } }
第二步Presenter层
/** * 定义业务逻辑 */ 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); } }); } }
第三步实现Mode层
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()); } }); } }
BaseMvpFragment主要封装对Presenter的实例化.
BasePresenter实现在Presenter中持有View的引用.
public abstract class BasePresenter<T> { /*这个基类的Presenter 主要的作用就是将当前Presenter持有的view 在合适的时候给清除掉*/ public T mView; public void attach(T mView) { this.mView = mView; } public void dettach() { mView = null; } }
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(); }
参考学习
Android单排上王者系列之Android MVP解析实践
转载请注明来源:MVP模式入门