日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
淺淡MVP的實戰(zhàn)演習,讓代碼結(jié)構(gòu)更簡單~

前言

講道理,這次是真的筆者很久都沒有更新blog了,主要最近維護的框架問題也是層出不窮,而且對技術(shù)交流群的解答也讓我身心疲憊,所以在這里跟關(guān)注我的人說聲抱歉,沒有定期給你們帶來福利,那么這里就給大家?guī)硪粋€重磅福利:愛吖妹紙——Retrofit & RxJava & MVP & Butterknife 的完整App.

講到最近讓我身心疲憊的問題解答,無疑是讓我在開源的路上越走越遠,雖然我不是技術(shù)大牛,卻依然被一些很簡單的問題輪番轟炸,其實筆者的內(nèi)心真的是拒絕的。不得不說,寫給技術(shù)群內(nèi)的你和群主,為什么你提問,而總沒人回你!寫的挺好。

概述

廢話也不多說,對于MVP(Model View Presenter),我相信大多數(shù)人都能說出一些的,“MVC的演化版本”,“讓Model和View完全解耦”等等,但用過MVP的人一定會覺得,在Android中,代碼很清晰,不過多了很多類。對于大多數(shù)人而言,在看MVP的Demo的時候,一眼便是慢慢的nice,然而讓自己來寫個例子,卻很頭疼寫不出來。但的確MVC模式寫起來更加像是順水推舟。只需要把自己的業(yè)務(wù)邏輯一股腦的放進Activity就成功完事兒。

不得不說,之前我們項目中的確也是用的MVC在編寫的。很簡單的會發(fā)現(xiàn)隨便一個Activity代碼都是幾百上千行,甚至還有一萬行以上的??雌饋淼拇_那么一回事兒,但是細想這個View對于布局文件,其實能做的事情特別少,實際上關(guān)于該布局文件中的數(shù)據(jù)綁定的操作,事件處理的操作都在Activity中,造成了Activity既想View又像Controller,鄙棄代碼上的不美觀來說,對于后面的閱讀代碼真的是吃力。

不信?你瞧瞧。

也許業(yè)務(wù)邏輯比較簡單的功能用MVC沒什么,但是想沒想過,如果你產(chǎn)品后面改需求怎么辦?是的,你接受產(chǎn)品需求的強奸,但還是只有忍辱偷生。在日漸復(fù)雜的業(yè)務(wù)邏輯上,你的Activity和Fragment代碼越來越多,最終導(dǎo)致代碼爆炸,難以維護。

網(wǎng)上瀏覽一圈,發(fā)現(xiàn)講MVP的文章比比皆是,可見MVP的歡迎度,但大多數(shù)文章都只是講理論,稍微好點的會附帶一個簡單的登錄的Demo。然而,一個簡單的demo很難讓初次接觸MVP模式的人掌握它的使用。所以愛吖妹紙應(yīng)運而生。

什么是MVP

當然不能跑題,前面對 MVP 做了簡單的概述,下面還是用一個簡單的圖表示一下。

如上圖所示,在項目中 View 和 Model 并不直接交互,而是使用 Presenter 作為 View 和 Model 之間的橋梁。其中 Presenter 中同時持有 View 層以及 Model 層的 Interface 的引用,而 View 層持有 Presenter 層 Interface 的引用,當 View 層某個頁面需要展示某些數(shù)據(jù)的時候,首先會調(diào)用Presenter 層的某個接口,然后 Presenter 層會調(diào)用 Model 層請求數(shù)據(jù),當 Model 層數(shù)據(jù)加載成功之后會調(diào)用 Presenter 層的回調(diào)方法通知 Presenter 層數(shù)據(jù)加載完畢,*** Presenter 層再調(diào)用 View 層的接口將加載后的數(shù)據(jù)展示給用戶。這就是 MVP 模式的核心過程。

這樣分層的好處就是大大減少了Model與View層之間的耦合度。一方面可以使得View層和Model層單獨開發(fā)與測試,互不依賴。另一方面Model層可以封裝復(fù)用,可以極大的減少代碼量。當然,MVP還有其他的一些優(yōu)點,這里不再贅述。

功能展示

這里就給大家隨便看看干貨板塊的功能吧。

布局相當簡單。

 
 
 
 
  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,支持下拉刷新和上拉加載數(shù)據(jù)。所以我們的 Presenter 和 View 只需要定義一下簡單的方法。

1)加載數(shù)據(jù)的過程中顯示加載的進度條;

2)加載數(shù)據(jù)成功提醒 Adapter 刷新數(shù)據(jù);

3)加載失敗談窗提醒用戶相關(guān)信息;

4)加載結(jié)束隱藏進度條;

 
 
 
 
  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 實現(xiàn)類。

 
 
 
 
  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()+" 列表數(shù)據(jù)獲取失?。?);
  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,用于展示數(shù)據(jù)。

  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的實戰(zhàn)演習,讓代碼結(jié)構(gòu)更簡單~
    標題來源:http://www.5511xx.com/article/ccshshd.html