美文网首页Weli收藏的文章AndroidandroidAndroid控件
MVP框架搭建(2):mvp的分块演示

MVP框架搭建(2):mvp的分块演示

作者: tmyzh | 来源:发表于2018-03-22 19:55 被阅读565次

    上一篇主要讲mvp的概念,怎么将原来一个activity分成model,presenter,activity三部分,不熟悉的可以点击下面链接
    MVP框架搭建(1):界面数据分离
    这一片主要讲如何将封装三部分的基类,以及演示三部分如何串联起来。

    BaseView
    当presenter收到网络返回的响应时,通过baseView传递给activity更新界面

    public interface DaggerBaseView {
    
        /**
         * 显示网络请求加载转圈
         */
        void  showLoading();
    
        /**
         * 关闭加载转圈
         */
        void hideloading();
    
        /**
         * 吐息一些信息
         * @param msg
         */
        void  showToast(String msg);
        void showErr();
        Context getContext();
    }
    

    BaseModel
    采用了泛型,防止因为数据类型不一致导致创建多个model的基类

    public interface DaggerBaseModel <T>{
        /**
         * 创建接口对象
          */
        void getNetApi();
    
        /**
         * 发送get请求
         * @param callback
         */
         void requestGetAPI( BaseCallBack<T> callback);
    
        /**
         * 发送post请求
         * @param params
         * @param callBack
         */
        void requestPostAPI( Map params, BaseCallBack<T> callBack);
    

    BasePresenter
    也用到了泛型,因为每个Presenter里都需要一个View对象,所以用了一个继承BaseView的泛型对象

    public abstract class DaggerBasePresenter<V extends DaggerBaseView,T> implements BaseCallBack<T> {
    
        private V mvpView;
    
        /**
         * 绑定view,在获取网络响应之后通过view传递给activity
         * @param mvpView
         */
        public void attachView(V mvpView){
            this.mvpView=mvpView;
        }
    
        /**
         * 解绑view
         */
        public void detachView(){
            this.mvpView=null;
        }
    
        /**
         * 判断是否解绑 在网络请求时页面被终结,导致后续出现nullpointException
         * @return
         */
        public boolean isViewAttached(){
            return mvpView!=null;
        }
    
        public V getMvpView(){
            return mvpView;
        }
    
        /**
         * 在页面对象创建完成后调用,可以用来初始化数据层对象
         */
        public abstract void onStart();
    }
    

    BaseActivity
    使用了一个presenter的泛型,一个view的泛型, 每个逻辑不同的页面要生成不同的view和presenter

    public abstract class DaggerBaseActivity<V extends DaggerBaseView,T extends DaggerBasePresenter> extends Activity implements DaggerBaseView {
    
        protected T presenter;
        private ProgressDialog progressDialog;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(getLayoutRes());
            //将当前activity加入自定义的app管理中
            AppManager.getInstance().addActivity(this);
            presenter=creatPresenter();
            if(presenter!=null){
                //绑定当前页面的view,用于presnter获取数据之后控制activity的变化
                presenter.attachView((V)this);
            }
            ButterKnife.bind(this);
            progressDialog=new ProgressDialog(this);
            progressDialog.setCancelable(false);
            init(savedInstanceState);
            if(presenter!=null){
                presenter.onStart();
            }
        }
    
        /**
         * 做一些初始化操作
         * @param savedInstanceState
         */
        protected abstract void init(Bundle savedInstanceState);
    
        /**
         * 指定需要加载的布局文件
         * @return
         */
        protected abstract int getLayoutRes();
    
        /**
         * 创建presenter对象
         */
        protected abstract T creatPresenter();
    
        /**
         * 使用presenter对象
         * @return
         */
        public T getPresnter(){
           return presenter;
        }
    
        @Override
        public void showLoading() {
            progressDialog.show();
        }
    
        @Override
        public void hideloading() {
            progressDialog.hide();
        }
    
        @Override
        public void showToast(String msg) {
            Toast.makeText(getContext(),msg,Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void showErr() {
            Toast.makeText(getContext(),"出错",Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public Context getContext() {
            return DaggerBaseActivity.this;
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if(presenter!=null){
                presenter.detachView();
            }
            presenter=null;
            AppManager.getInstance().finishActivity(this);
        }
    }
    

    需要导入的三方依赖

        compile 'com.jakewharton:butterknife:7.0.1'
        //rxjava与retrofit
        compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
        compile 'io.reactivex.rxjava2:rxjava:2.0.7'
        // Android 支持 Retrofit
        compile 'com.squareup.retrofit2:retrofit:2.1.0'
        // 衔接 Retrofit & RxJava
        // 此处一定要注意使用RxJava2的版本
        compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
        // 支持Gson解析
        compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    
    下面展示一个例子,演示怎么使用

    api接口 这里用到是爱词霸的公开接口做测试,大家可以在网上查找

    public interface GetDatas {
        @GET(Urls.test)
        Observable<Translation> getCall();
    }
    

    model实现获取网络数据的方法

    public class YoudaoDataModel implements DaggerBaseModel<String> {
    
        GetDatas getDatas;
    
        @Override
        public void getNetApi() {
            getDatas= ApiFactory.getInstance().create(GetDatas.class);
        }
    
        @Override
        public void requestGetAPI(final BaseCallBack<String> callback) {
            getDatas.getCall()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<Translation>() {
                @Override
                public void onSubscribe(Disposable d) {
                    Log.e("yzh","onSubscribe");
                }
    
                @Override
                public void onNext(Translation translation) {
                    Log.e("yzh","oNext--"+translation.show());
                    callback.onSuccess(translation.show());
                }
    
                @Override
                public void onError(Throwable e) {
                    Log.e("yzh","onError--"+e.getMessage());
                    callback.onFailure(e.getMessage());
                }
    
                @Override
                public void onComplete() {
                    Log.e("yzh","onComplete--");
                    callback.onComplete();
                }
            });
        }
    
        @Override
        public void requestPostAPI( Map params, BaseCallBack<String> callBack) {
        }
    

    view继承基类,添加当前页面需要的额外方法

    public interface YouDaoView extends DaggerBaseView {
        /**
         * 加载网络请求回来的数据
         * @param msg
         */
        void showNetData(String msg);
    }
    

    presenter现在在基类中是实现callback,在具体页面时用泛型传递具体的数据类型,之前是在网络请求的时候直接new一个callback,还没对比出哪个更好一些

    public class YouDaoPresenter extends DaggerBasePresenter<YouDaoView,String> {
    
        private YoudaoDataModel youdaoDataModel;
    
        @Override
        public void onStart() {
            youdaoDataModel=new YoudaoDataModel();
            youdaoDataModel.getNetApi();
        }
    
        public void getNetData(){
            if(!isViewAttached()){
                //已经解绑了
                return;
            }
            getMvpView().showLoading();
            youdaoDataModel.requestGetAPI(this);
        }
    
        @Override
        public void onSuccess(String data) {
            if(isViewAttached()){
                getMvpView().showNetData(data);
            }
        }
    
        @Override
        public void onFailure(String msg) {
            if(isViewAttached()){
                getMvpView().showToast(msg);
                getMvpView().hideloading();
            }
        }
    
        @Override
        public void onError() {
            if(isViewAttached()){
                getMvpView().hideloading();
                getMvpView().showErr();
            }
        }
    
        @Override
        public void onComplete() {
            if(isViewAttached()){
                getMvpView().hideloading();
            }
        }
    

    Activity

    public class YoudaoActivity extends DaggerBaseActivity<YouDaoView,YouDaoPresenter> implements YouDaoView {
    
       @Bind(R.id.tv_get_data)
       TextView tv_get_data;
       @Bind(R.id.tv_data)
       TextView tv_data;
    
        @Override
        public void showNetData(String msg) {
            tv_data.setText(msg);
        }
    
        @Override
        protected void init(Bundle savedInstanceState) {
    
        }
    
        @Override
        protected int getLayoutRes() {
            return R.layout.activity_youdao;
        }
    
        @Override
        protected YouDaoPresenter creatPresenter() {
            return new YouDaoPresenter();
        }
    
        @OnClick(R.id.tv_get_data)
        public void getNetData(){
            presenter.getNetData();
        }
    }
    
    演示效果

    。。。。gif传不上去,各位看官就自行code吧

    下一步会优化网络请求方式这一块,包括返回数据结构的优化,大家可以看到这些类都带了一个Dagger,没错我就是要用Dagger做解耦,但是我好像在入门到放弃的道路上越走越远了

    相关文章

      网友评论

      • mrzhqiang:哈哈,最新的 dagger2 有简易的依赖注入实现,比如通过继承 DaggerApplication 去实现全局依赖注入。😀😀
        tmyzh:@mrZ_9740 确实是四维的转变
        mrzhqiang:@tmyzh 看三遍你就知道了,这跟最初学 Android 一样,是思维的转变,肯定需要一个过程。
        tmyzh:@mrZ_9740 我都觉得自己在为难自己了,大多数注解都了解了,但是觉得会用不上手,怕入坑

      本文标题:MVP框架搭建(2):mvp的分块演示

      本文链接:https://www.haomeiwen.com/subject/cytzqftx.html