转载

Android MVP 实例运用

Android MVP介绍

随着技术的发展,Activity(View) 做的事情越来越多,动辄几百上千行的代码使得 Activity 越来越臃肿。为了更好的划分视图(View)和模型(Model)之间的职责,让 View 只处理数据的展示和用户的交互,把数据的处理交由 Model 处理。

在MVP模式里通常包含4个要素:

  1. View:负责绘制UI元素、与用户进行交互(在Android中体现为Activity);
  2. View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;
  3. Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);
  4. Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。

Android MVP 实例运用

Android MVP 好处

MVP模式可以让显示界面和数据分离,我们开发的应用可以分离至少三层,这样也可以进行独立测试。更加的好维护(代码复用)数据分离有利于信息的隐蔽等等优点,相比较他的优点,缺点就可以忽略了。

Android MVP 实例

下图是采用MVP做的一个列表页面,实现了刷新,加载更多的功能。

Android MVP 实例运用

目录结构

Android MVP 实例运用

View 层

view 层的接口 用来与Presenter进行交互

public interface MovieView extends MVPView {       void showLoading();       void hideLoading();       void showSwipeRefresh();       void hideSwipeRefresh();       boolean isSwipeRefresh();       void showMovies(List<Movies> movieList);       void appendMovies(List<Movies> movieList);       void showToast(String content);       boolean isTheListEmpty();   }   

view 接口的实现类(Activity)

@Override     protected void onCreate(BundlesavedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         ButterKnife.bind(this);         // 设置 presenter         moviePresenter = new MoviePresenter();         moviePresenter.attachView(this);         initializeSwipe();         initializeRecycler();     }       /**      * 初始化SwipeRefreshLayout和设置下拉刷新事件      * */     private void initializeSwipe() {         mainSwipe.setColorSchemeResources(                 android.R.color.holo_blue_light,                 android.R.color.holo_red_light,                 android.R.color.holo_orange_light,                 android.R.color.holo_green_light);         mainSwipe.setSize(SwipeRefreshLayout.LARGE);         mainSwipe.setProgressViewEndTarget(true, 200);         mainSwipe.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {             @Override             public void onRefresh() {                 moviePresenter.refresh();             }         });     }       /**      * 初始化RecyclerView      * */     private void initializeRecycler() {         mainRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));         adaper = new MovieAdaper();         adaper.setRecyclerListListener(this);         mainRecyclerView.setAdapter(adaper);         mainRecyclerView.setOnScrollListener(recyclerScrollListener);     }       /*---------省略部分代码--------------*/       /**      * 加载更多的判断和触发      * */     private RecyclerView.OnScrollListenerrecyclerScrollListener = new RecyclerView.OnScrollListener() {         @Override         public void onScrolled(RecyclerViewrecyclerView, int dx, int dy) {             super.onScrolled(recyclerView, dx, dy);               int visibleItemCount    = mainRecyclerView.getLayoutManager().getChildCount();             int totalItemCount      = mainRecyclerView.getLayoutManager().getItemCount();             int pastVisibleItems    = ((GridLayoutManager) mainRecyclerView.getLayoutManager())                     .findFirstVisibleItemPosition();               if((visibleItemCount + pastVisibleItems) >= totalItemCount && !moviePresenter.isLoading()                     && !moviePresenter.isLast()) {                 moviePresenter.loadMore();             }         }     };   

Presenter

处理网络请求以及数据分发

package com.jwenfeng.moviemvp.presenters;   importandroid.util.Log;   importcom.jwenfeng.moviemvp.model.Movies; importcom.jwenfeng.moviemvp.view.MovieView;   importjava.util.List;   importcn.bmob.v3.BmobQuery; importcn.bmob.v3.listener.FindListener;   /** * 当前类注释: * 项目名:MovieMVP * 包名:com.jwenfeng.moviemvp.presenters * 作者:jinwenfeng on 16/4/23 16:38 * 邮箱:823546371@qq.com * QQ: 823546371 * 公司:南京穆尊信息科技有限公司 * © 2016 jinwenfeng * ©版权所有,未经允许不得传播 */ public class MoviePresenter extends Presenter {       private MovieViewmovieView;       private int limit = 8;        // 每页的数据是8条     private int curPage = 0;        // 当前页的编号,从0开始       private boolean isLoading = false;     private boolean isLast = false;       public void attachView(MovieViewmovieView) {         this.movieView = movieView;     }       /**      * 获取数据      * */     public void getData() {         BmobQuery<Movies> query = new BmobQuery<>();         query.setSkip(curPage * limit);         query.setLimit(limit);         query.findObjects(movieView.getContext(), new FindListener<Movies>() {             @Override             public void onSuccess(List<Movies> list) {                 if (list.size() > 0) {                     if (movieView.isTheListEmpty()) {                         movieView.hideLoading();                     }                     if (movieView.isSwipeRefresh()) {                         movieView.showMovies(list);                         movieView.hideSwipeRefresh();                     } else {                         Log.e("MoviePresenter",curPage+"----"+list.size());                         movieView.appendMovies(list);                     }                     curPage++;                     isLast = false;                     isLoading = false;                 } else {                     isLast = true;                     isLoading = false;                     movieView.showToast("没有更多数据了");                 }             }               @Override             public void onError(int i, String s) {                 Log.e("MoviePresenter", i + "---" + s);                 movieView.showToast("查询失败:" + s);             }         });     }       /**      * 加载更多      * */     public void loadMore() {         if (!isLast && !isLoading){             isLoading = true;             getData();         }     }       /**      * 刷新      * */     public void refresh() {         curPage = 0;         movieView.showSwipeRefresh();         isLoading = true;         getData();     }       @Override     public void start() {         if (movieView.isTheListEmpty()) {             movieView.showLoading();             isLoading = true;             getData();         }     }       @Override     public void stop() {       }       public boolean isLoading() {         return isLoading;     }       public boolean isLast() {         return isLast;     } }   

Model

最后的Model就不贴了,就是一个bean

模式没有固定的,适合自己的就是最好的,欢迎关注,不足之处请指教,如果有兴趣可以参考放在GitHub上的源码

github地址: https://github.com/823546371/MovieMVP

本文地址: http://jwenfeng.com/?p=199

尊重原创,转载请注明:From 晓峰残月(http://jwenfeng.com) 侵权必究!

原文  http://jwenfeng.com/archives/199
正文到此结束
Loading...