美文网首页
Android,Mvp模式学习

Android,Mvp模式学习

作者: HWilliamgo | 来源:发表于2018-02-09 16:11 被阅读14次

    title: Mvp项目学习

    今天用我们用MVP模式来完成一个简单的登录界面的实现。
    业务需求:

    • 用户输入用户名和密码之后,按下登录按钮,跳转到另一个Activity。
      • 这里面隐含的一些含义有:检查用户名和密码(网络访问)
      • 点击登录按钮,对网络返回结果判断并处理(设置监听器)

    由于我们这里是简化版本的,所以不写网络访问的代码,用一个延时的handler来模拟就行了。


    image.png

    MVP模式的思路是:

    • 创建Model接口,View接口,Presenter接口。
    • View接口:根据业务或者UI设计师给的图片来定制我们的View接口中应该有哪些方法,比如显示进度条,跳转界面,只要用户能操作的或者用户看得到的可交互的东西,都需要考虑是否要写进View接口中。
    • Model接口:根据View接口中的方法,设计Model接口中的方法,Model接口就是用来对数据进行处理的,UI层的交互数据将会流到这里,比如EditText输入了用户名,那么用户名就经由Presenter的逻辑处理最终来到Model接口,Model接口比如实现了网络访问操作,此时将数据处理了拿到返回结果,再传回给Presenter,经由Presenter传递给View。
    • Presenter接口:根据View接口中的方法来设计对应的方法,并且方法一般都和Model层进行交互。

    View层接口的设计:

    那么首先看到界面的图片,我们按照用户和UI交互的几个地方设计方法就行了:

    • 点击登录,显示登录进度,用一个progressBar。
    • 点击登录可能出现:
      • 用户名错误提示:设置用户名错误提示动画
      • 密码错误提示:设置密码错误提示动画
      • 用户名密码正确,跳转至主界面Activity
        那么对应的LoginView接口为:
    public interface ILoginView {
        void showProgressBar();
        void hideProgressBar();
        void setUserNameError();
        void setPasswordError();
        void JumpToActivity();
    }
    

    那么对应的登录界面的Activity只要实现该接口并正确地实现每个接口所描述的方法就行了。回头在Presenter里面用ILoginView的引用调用对应的方法,即可从Presenter层去改变UI界面。

    Model层接口的设计

    Model层是用来接收数据(从View层发送过来的数据),处理数据,并返回数据(返回给View层来展示给用户)的,所以Model接口的方法设计要依照我们要处理的数据。
    这里要处理的数据是:---------用户名和密码
    此外还要设计监听器,为了便于管理,监听器就放在对应的Model层接口里面
    代码:

    public interface ILoginModel {
        interface OnLoginListener{
            void onSuccess();
            void onUsernameWrong();
            void onPasswordWrong();
        }
        void login(String username,String password,ILoginModel.OnLoginListener listener);
    }
    

    实现类

    public class LoginModelImp implements ILoginModel {
        @Override
        public void login(final String username, final String password, final OnLoginListener listener) {
            //此处应该是有网络请求的,比如调用OkHttp或者RxJava什么的。
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (TextUtils.isEmpty(username)){
                        listener.onUsernameWrong();
                        return;
                    }
                    if (TextUtils.isEmpty(password)){
                        listener.onPasswordWrong();
                        return;
                    }
                    listener.onSuccess();
    
                }
            },1500);
        }
    }
    

    在这里的OnLoginListener调用的每一个方法最终的结果都是去View层去改变UI视图来和用户交互,而Model层不能直接和View层通信,那么只能借助Presenter来实现监听器接口,因为Presenter里面有双方(M和V)的引用,所以可以轻易地调用View层的方法去改变UI。

    Presenter层接口的设计

    Presenter层是用来桥接Model层和View层的,所以方法应该用于让M和V之间通信

    public interface ILoginPresenter {
        void onLogin(String username,String password);
        void onViewDestroy();
    }
    

    实现类

    public class LoginPresenterImp  implements ILoginPresenter,ILoginModel.OnLoginListener{
        private ILoginModel loginModel;
        private ILoginView loginView;
    
        public LoginPresenterImp(ILoginView loginView){
            this.loginView=loginView;
            this.loginModel=new LoginModelImp();
        }
    
        @Override
        public void onLogin(String username,String password) {
            if (loginView!=null){
                loginView.showProgressBar();
            }
            loginModel.login(username,password,this);
        }
    
        @Override
        public void onViewDestroy() {
            //解除View和Presenter的绑定
            loginView=null;
        }
        //----------------------------------------------下面是OnLoginListener
        @Override
        public void onSuccess() {
            loginView.hideProgressBar();
            loginView.JumpToActivity();
        }
    
        @Override
        public void onUsernameWrong() {
            loginView.setUserNameError();
            loginView.hideProgressBar();
        }
    
        @Override
        public void onPasswordWrong() {
            loginView.setPasswordError();
            loginView.hideProgressBar();
        }
    }
    

    最后是View层的实现类,即LoginActivity

    public class LoginActivity extends AppCompatActivity implements ILoginView{
        ILoginPresenter loginPresenter;
    
        ProgressBar progressBar;
        EditText usernameE,passwordE;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initiateView();
            loginPresenter=new LoginPresenterImp(this);
    
            findViewById(R.id.loginBtn).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    loginPresenter.onLogin(usernameE.getText().toString(),passwordE.getText().toString());
                }
            });
        }
    
        private void initiateView() {
            usernameE=findViewById(R.id.username);
            passwordE=findViewById(R.id.password);
            progressBar=findViewById(R.id.loginProgressBar);
        }
    
        @Override
        public void showProgressBar() {
            progressBar.setVisibility(View.VISIBLE);
        }
    
        @Override
        public void hideProgressBar() {
            progressBar.setVisibility(View.INVISIBLE);
        }
    
        @Override
        public void setUserNameError() {
            usernameE.setError("用户名错误");
        }
    
        @Override
        public void setPasswordError() {
            passwordE.setError("密码错误");
        }
    
        @Override
        public void JumpToActivity() {
            startActivity(new Intent(this, Main2Activity.class));
            this.finish();
        }
    
        @Override
        protected void onDestroy() {
            loginPresenter.onViewDestroy();
            super.onDestroy();
        }
    }
    

    持有Presenter的引用,调用Presenter中的方法,而Presenter中又有Model的引用,间接地将数据传输给Model层去处理


    接下来模拟一次正常的用户操作,输入用户名和密码并点击登录,那么事件发生的流程图如下:

    结束


    github项目地址:MvpFirst

    相关文章

      网友评论

          本文标题:Android,Mvp模式学习

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