美文网首页MVP-MVC-MVVM安卓Android开发
Android框架搭建(1):界面和数据的分离

Android框架搭建(1):界面和数据的分离

作者: tmyzh | 来源:发表于2018-03-13 19:25 被阅读1085次

    采用MVP构架,让activity只做ui的变化,数据的展示,让presenter做数据的处理,数据的传递,让Model做数据的网络获取。
    这样就可以将原本全部存在Activity的成百上千行代码分离出来,增加代码可读性。只不过增加了类的个数。
    下面演示一下流程图


    image

    展示一下实现Activity界面和数据拆分的几个类

    MvpCallBack接口

    MvpCallback接口是Model向presenter层传递数据的载体:

    public interface MvpCallback {
    
        /**
         * 数据请求成功
         * @param data
         */
        void onSuccess(String data);
    
        /**
         * 数据请求成功 解析失败
         * @param msg
         */
        void onFailure(String msg);
    
        /**
         * 数据请求失败
         */
        void onError();
    
        /**
         * 一次请求完成 不管成功或者失败
         */
        void onComplete();
    }
    

    MvpModel中提供了向网络获取数据的方法,这里用handler.postDelay实现一个延时操作来模拟网络请求的情况

    public class MvpModel {
    
        public  enum Action{
            NORMAL,FAILUER,ERROR
        }
    
        public static void getNetData(final Action param,final MvpCallback callback){
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    switch (param){
                        case NORMAL:
                            callback.onSuccess("请求成功");
                            break;
                        case FAILUER:
                            callback.onFailure("请求失败,参数有误");
                            break;
                        case ERROR:
                            callback.onError();
                            break;
                    }
                    callback.onComplete();
                }
            },2000);
        }
    

    MvpView接口是Presenter层向Activity层传递数据的载体,在presenter接受网络数据响应之后通过View接口让activity更新界面。

    public interface MvpView {
        /**
         * 显示正在加载进度框
         */
        void showLoading();
    
        /**
         * 隐藏正在加载进入框
         */
        void hideLoading();
    
        /**
         * 请求数据成功后,调用此接口显示数据
         * @param data
         */
        void showData(String data);
    
        /**
         * 数据请求失败,调用
         * @param msg
         */
        void showFailureMessage(String msg);
    
        /**
         * 当数据请求异常,调用此接口提示
         */
        void showErrorMessage();
    }
    

    Presenter类是具体的逻辑业务处理类,Presenter类的构造方法中有一个View接口的参数,是为了能够通过View接口通知Activity进行更新界面等操作。

    public class MvpPresenter {
    
        //View接口
        private MvpView mvpView;
    
        public MvpPresenter(MvpView view){
            this.mvpView=view;
        }
    
        public void getData(MvpModel.Action param){
            mvpView.showLoading();
            MvpModel.getNetData(param, new MvpCallback() {
                @Override
                public void onSuccess(String data) {
                    mvpView.showData(data);
                }
    
                @Override
                public void onFailure(String msg) {
                    mvpView.showFailureMessage(msg);
                }
    
                @Override
                public void onError() {
                    mvpView.showErrorMessage();
                }
    
                @Override
                public void onComplete() {
                    mvpView.hideLoading();
                }
            });
        }
    }
    

    MainActivity 继承了一个MvpView类 并且定义了一个MvpPresenter对象

    public class MainActivity extends AppCompatActivity implements MvpView {
    
        private TextView tv_s;
        private TextView tv_f;
        private TextView tv_e;
    
        ProgressDialog progressDialog;
        MvpPresenter presenter;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Log.e("yzh","1111111");
    
            tv_s=(TextView)findViewById(R.id.tv_s);
            tv_s.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    presenter.getData(MvpModel.Action.NORMAL);
                }
            });
            tv_f=(TextView)findViewById(R.id.tv_f);
            tv_f.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    presenter.getData(MvpModel.Action.FAILUER);
                }
            });
            tv_e=(TextView)findViewById(R.id.tv_e);
            tv_e.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    presenter.getData(MvpModel.Action.ERROR);
                }
            });
    
            // 初始化进度条
            progressDialog = new ProgressDialog(this);
            progressDialog.setCancelable(false);
            progressDialog.setMessage("正在加载数据");
    
            //初始化Presenter
            presenter = new MvpPresenter(this);
    
            //presenter2绑定view
    //        presenter2=new MvpPresenter2();
    //        presenter2.attachView(this);
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
    //        presenter2.detachView();
        }
    
        @Override
        public void showLoading() {
            if(!progressDialog.isShowing()){
                progressDialog.show();
            }
        }
    
        @Override
        public void hideLoading() {
            if(progressDialog.isShowing()){
                progressDialog.dismiss();
            }
        }
    
        @Override
        public void showData(String data) {
            if(!TextUtils.isEmpty(data)){
                Toast.makeText(MainActivity.this,data,Toast.LENGTH_SHORT).show();
            }
    
        }
    
        @Override
        public void showFailureMessage(String msg) {
            if(!TextUtils.isEmpty(msg)){
                Toast.makeText(MainActivity.this,msg,Toast.LENGTH_SHORT).show();
            }
        }
    
        @Override
        public void showErrorMessage() {
            Toast.makeText(MainActivity.this,"网络请求出错",Toast.LENGTH_SHORT).show();
        }
    }
    

    下一步将提取冗余代码做父类,并且使用泛型数据,来防止多样的数据类型导致更多类的生产。
    MVP框架搭建(2):mvp的分块演示

    相关文章

      网友评论

      • Ello_Orld:谢谢,写的很好
      • 深爱着伊豆的流云:加油,慢慢来!!
      • AWeiLoveAndroid:建议把网络层单独抽离出去 封装成一个库 方便维护 在p层里面去引用网络层的库 这样达到了更好地维护管理 你却换网络库也没有影响 最后在v层只管写网络回调就ok了
        tmyzh:@七岁就狠拽 retrofit就是封装的 retrofit就是封装的OKhttp啊
        七岁就狠拽:Volley和Okhttp切换还比较好操作, 如果是Volley和Retrofit之间切换要咋整??
        tmyzh:@AWeiLoveAndroid 谢谢建议,会思考一下,不过不知道有没有能力搞好 第一次搞这样的东西

      本文标题:Android框架搭建(1):界面和数据的分离

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