浅淡MVP的实战演习,让代码结构更简单~

前言

讲道理,这次是真的笔者很久都没有更新blog了,主要最近维护的框架问题也是层出不穷,而且对技术交流群的解答也让我身心疲惫,所以在这里跟关注我的人说声抱歉,没有定期给你们带来福利,那么这里就给大家带来一个重磅福利:爱吖妹纸——Retrofit & RxJava & MVP & Butterknife 的完整App.

讲到最近让我身心疲惫的问题解答,无疑是让我在开源的路上越走越远,虽然我不是技术大牛,却依然被一些很简单的问题轮番轰炸,其实笔者的内心真的是拒绝的。不得不说,写给技术群内的你和群主,为什么你提问,而总没人回你!写的挺好。

概述

废话也不多说,对于MVP(Model View Presenter),我相信大多数人都能说出一些的,“MVC的演化版本”,“让Model和View完全解耦”等等,但用过MVP的人一定会觉得,在Android中,代码很清晰,不过多了很多类。对于大多数人而言,在看MVP的Demo的时候,一眼便是慢慢的nice,然而让自己来写个例子,却很头疼写不出来。但的确MVC模式写起来更加像是顺水推舟。只需要把自己的业务逻辑一股脑的放进Activity就成功完事儿。

不得不说,之前我们项目中的确也是用的MVC在编写的。很简单的会发现随便一个Activity代码都是几百上千行,甚至还有一万行以上的。看起来的确那么一回事儿,但是细想这个View对于布局文件,其实能做的事情特别少,实际上关于该布局文件中的数据绑定的操作,事件处理的操作都在Activity中,造成了Activity既想View又像Controller,鄙弃代码上的不美观来说,对于后面的阅读代码真的是吃力。

不信?你瞧瞧。

也许业务逻辑比较简单的功能用MVC没什么,但是想没想过,如果你产品后面改需求怎么办?是的,你接受产品需求的强奸,但还是只有忍辱偷生。在日渐复杂的业务逻辑上,你的Activity和Fragment代码越来越多,最终导致代码爆炸,难以维护。

网上浏览一圈,发现讲MVP的文章比比皆是,可见MVP的欢迎度,但大多数文章都只是讲理论,稍微好点的会附带一个简单的登录的Demo。然而,一个简单的demo很难让初次接触MVP模式的人掌握它的使用。所以爱吖妹纸应运而生。

什么是MVP

当然不能跑题,前面对 MVP 做了简单的概述,下面还是用一个简单的图表示一下。

如上图所示,在项目中 View 和 Model 并不直接交互,而是使用 Presenter 作为 View 和 Model 之间的桥梁。其中 Presenter 中同时持有 View 层以及 Model 层的 Interface 的引用,而 View 层持有 Presenter 层 Interface 的引用,当 View 层某个页面需要展示某些数据的时候,首先会调用Presenter 层的某个接口,然后 Presenter 层会调用 Model 层请求数据,当 Model 层数据加载成功之后会调用 Presenter 层的回调方法通知 Presenter 层数据加载完毕,*** Presenter 层再调用 View 层的接口将加载后的数据展示给用户。这就是 MVP 模式的核心过程。

这样分层的好处就是大大减少了Model与View层之间的耦合度。一方面可以使得View层和Model层单独开发与测试,互不依赖。另一方面Model层可以封装复用,可以极大的减少代码量。当然,MVP还有其他的一些优点,这里不再赘述。

功能展示

这里就给大家随便看看干货板块的功能吧。

布局相当简单。

 
 
 
 
  1.     xmlns:android="http://schemas.android.com/apk/res/android"
  2.     xmlns:app="http://schemas.android.com/apk/res-auto"
  3.     android:id="@+id/swipe_refresh_layout"
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent">
  6.     
  7.         android:id="@+id/recyclerView"
  8.         android:layout_width="match_parent"
  9.         android:layout_height="match_parent"/>
  10.  

干货模块,也就是一个Fragment,里面有一个RecyclerView,支持下拉刷新和上拉加载数据。所以我们的 Presenter 和 View 只需要定义一下简单的方法。

1)加载数据的过程中显示加载的进度条;

2)加载数据成功提醒 Adapter 刷新数据;

3)加载失败谈窗提醒用户相关信息;

4)加载结束隐藏进度条;

 
 
 
 
  1. public interface CategoryContract {    
  2.     interface ICategoryView extends BaseView{ 
  3.         void getCategoryItemsFail(String failMessage);        
  4.         void setCategoryItems(CategoryResult categoryResult);        
  5.         void addCategoryItems(CategoryResult categoryResult);        
  6.         void showSwipeLoading();        
  7.         void hideSwipeLoading();        
  8.         void setLoading();        
  9.         String getCategoryName();        
  10.         void noMore();
  11.     }    interface ICategoryPresenter extends BasePresenter{        
  12.         void getCategoryItems(boolean isRefresh);
  13.     }

编写 Presenter 实现类。

 
 
 
 
  1. public class CategoryPresenter implements ICategoryPresenter {    
  2. private ICategoryView mCategoryICategoryView;    
  3. private int mPage = 1;    
  4. private Subscription mSubscription;    
  5. public CategoryPresenter(ICategoryView androidICategoryView) {
  6.         mCategoryICategoryView = androidICategoryView;
  7.     }    
  8.     @Override
  9.     public void subscribe() {
  10.         getCategoryItems(true);
  11.     }    
  12.     @Override
  13.     public void unSubscribe() {        
  14.         if (mSubscription != null  && !mSubscription.isUnsubscribed()){
  15.             mSubscription.unsubscribe();
  16.         }
  17.     }    @Override
  18.     public void getCategoryItems(final boolean isRefresh) {        
  19.         if (isRefresh) {
  20.             mPage = 1;
  21.             mCategoryICategoryView.showSwipeLoading();
  22.         } else {
  23.             mPage++;
  24.         }
  25.         mSubscription = NetWork.getGankApi()
  26.                 .getCategoryData(mCategoryICategoryView.getCategoryName(), GlobalConfig.CATEGORY_COUNT,mPage)
  27.                 .subscribeOn(Schedulers.io())
  28.                 .observeOn(AndroidSchedulers.mainThread())
  29.                 .subscribe(new Observer() {                    
  30.                     @Override
  31.                     public void onCompleted() {
  32.                     }                    
  33.                     @Override
  34.                     public void onError(Throwable e) {
  35.                         mCategoryICategoryView.hideSwipeLoading();
  36.                         mCategoryICategoryView.getCategoryItemsFail(mCategoryICategoryView.getCategoryName()+" 列表数据获取失败!");
  37.                     }                    
  38.                     @Override
  39.                     public void onNext(CategoryResult categoryResult) {                        
  40.                         if (isRefresh){
  41.                             mCategoryICategoryView.setCategoryItems(categoryResult);
  42.                             mCategoryICategoryView.hideSwipeLoading();
  43.                             mCategoryICategoryView.setLoading();
  44.                         }else {
  45.                             mCategoryICategoryView.addCategoryItems(categoryResult);
  46.                         }
  47.                     }
  48.                 });
  49.     }

编写Adapter,用于展示数据。

  1. class CategoryRecyclerAdapter extends CommonRecyclerAdapter implements 
  2. ListenerWithPosition.OnClickWithPositionListener{
  3.     CategoryRecyclerAdapter(Context context) {        
  4.         super(context, null, R.layout.item_category);
  5.     }    @Override
  6.     public void convert(CommonRecyclerHolder holder, ResultsBean resultsBean) {        
  7.         if (resultsBean != null) {            
  8.         ImageView imageView = holder.getView(R.id.category_item_img);            
  9.         if (ConfigManage.INSTANCE.isListShowImg()) { // 列表显示图片
  10.                 imageView.setVisibility(View.VISIBLE);                
  11.             String quality = "";                
  12.             if (resultsBean.images != null && resultsBean.images.size() > 0) {
  13.                     switch (ConfigManage.INSTANCE.getThumbnailQuality()) {                        
  14.                         case 0: // 原图
  15.                             quality = "";                            
  16.                             break;                        
  17.                         case 1: //
  18.                             quality = "?imageView2/0/w/400";                            
  19.                             break;                        
  20.                         case 2:
  21.                             quality = "?imageView2/0/w/190";                            
  22.                             break;
  23.                     }                    
  24.                     Glide.with(mContext)
  25.                             .load(resultsBean.images.get(0) + quality)
  26.                             .placeholder(R.mipmap.image_default)
  27.                             .error(R.mipmap.image_default)
  28.                             .into(imageView);
  29.                 } else { // 列表不显示图片
  30.                     Glide.with(mContext).load(R.mipmap.image_default).into(imageView);
  31.                 }
  32.             } else {
  33.                 imageView.setVisibility(View.GONE);
  34.             }
  35.             holder.setTextViewText(R.id.category_item_desc, resultsBean.desc == null ? "unknown" : resultsBean.desc);
  36.             holder.setTextViewText(R.id.category_item_author, resultsBean.who == null ? "unknown" : resultsBean.who);
  37.             holder.setTextViewText(R.id.category_item_time, TimeUtil.dateFormat(resultsBean.publishedAt));
  38.             holder.setTextViewText(R.id.category_item_src, resultsBean.source == null ? "unknown" : resultsBean.source);
  39.             holder.setOnClickListener(this, R.id.category_item_layout);
  40.         }
  41.     }    @Override
  42.     public void onClick(View v, int position, CommonRecyclerHolder holder) {
  43.   &n

    网站标题:浅淡MVP的实战演习,让代码结构更简单~
    本文URL:http://www.shufengxianlan.com/qtweb/news7/419207.html

    网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

    广告

    声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联