MVP git -androidmvpdemo的理解心得

1.因为之前的开发用的都是mvc模式,就是说页面和处理逻辑都是写在了一起,MVP框架个人的理解不是很透彻,所以就从GitHub上面找了一个MVP的demo,链接的下载地址是https://github.com/antoniolg/androidmvp,写一下个人的理解心得,纯属记录。

笼统来讲,mvp大家从百度都能看到的定义就是
在这里插入图片描述

话说起来很简单,但是理解的时候我们还是需要一些项目进行实际的理解,话不多说,先看一下项目结构图
在这里插入图片描述
这个demo的接口很简单,就是涉及到两个页面,一个是login的页面还有一个是Main页面,实现的功能也很简单,就是Login页面输入账号名和密码之后(只要不为空就可以),就跳到Main页面.
先不看他这个结构,我们先用MVC 的思考方式想一下这个问题——如果是MVC模式,就是在Activity中进行两个EditText是否为空的判断,如果不为空就登录跳转,中间跳转的过程加载一个进度条的显示和隐藏的控制逻辑。
但是既然是MVP肯定是不一样的处理方式,上图中的java结构图已经可以看见一些端倪。

LoginActivity页面如下图:
在这里插入图片描述
我们按顺序的方式LoginACtivity开始讲起,先看我们最熟悉的LoginActivity页面

public class LoginActivity extends AppCompatActivity implements LoginView {

    private ProgressBar progressBar;
    private EditText username;
    private EditText password;
    private LoginPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        progressBar = findViewById(R.id.progress);
        username = findViewById(R.id.username);
        password = findViewById(R.id.password);
        findViewById(R.id.button).setOnClickListener(v -> validateCredentials());

        presenter = new LoginPresenter(this, new LoginInteractor());
    }

    @Override
    protected void onDestroy() {
        presenter.onDestroy();
        super.onDestroy();
    }

    @Override
    public void showProgress() {
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideProgress() {
        progressBar.setVisibility(View.GONE);
    }

    @Override
    public void setUsernameError() {
        username.setError(getString(R.string.username_error));
    }

    @Override
    public void setPasswordError() {
        password.setError(getString(R.string.password_error));
    }

    @Override
    public void navigateToHome() {
        startActivity(new Intent(this, MainActivity.class));
        finish();
    }

    private void validateCredentials() {
        presenter.validateCredentials(username.getText().toString(), password.getText().toString());
    }
}

跟我们之前处理页面的逻辑不同之处在哪儿呢?
onCreate()函数里面有一个LoginPresenet类的对象,正常的登录按钮涉及到的处理逻辑的东西我们放到了presenter这个对象的中处理,除此以外呢,这个类实现了一个LoginView的接口,其实从名字里面我们就可以看出来,loginView就是MVC中的View的体现,我们代开代码页面看看这个接口中做了什么?

public interface LoginView {
    void showProgress();

    void hideProgress();

    void setUsernameError();

    void setPasswordError();

    void navigateToHome();
}

接口的里面东西看名字都知道了,就是一个登录页面的时候需要用到的一些页面控件相关的方法:比如显示进度条(和当前progress控件有关)和跳珠到主页面(和控件login有关)

我们回到Activity中可以看到是在主页面中实现LoginVIew接口方法的。

但是你会发现一个问题是:这个接口实现的方法并没有在这个Activity中生命周期中调用,、
那,我们是在哪里调用的这些方法的呢?
我们回看在onCreate()方法中,可以看到Presenter这个对象初始化的时候第一个参数就是我们当前的LoginView,我们可以猜测就是在Present中用到了当前接口的方法
来看看这个LoginPresenter,上代码

LoginPresenter.java

public class LoginPresenter implements LoginInteractor.OnLoginFinishedListener {

    private LoginView loginView;
    private LoginInteractor loginInteractor;

    LoginPresenter(LoginView loginView, LoginInteractor loginInteractor) {
        this.loginView = loginView;
        this.loginInteractor = loginInteractor;
    }

    public void validateCredentials(String username, String password) {
        if (loginView != null) {
            loginView.showProgress();
        }

        loginInteractor.login(username, password, this);
    }

    public void onDestroy() {
        loginView = null;
    }

    @Override
    public void onUsernameError() {
        if (loginView != null) {
            loginView.setUsernameError();
            loginView.hideProgress();
        }
    }

    @Override
    public void onPasswordError() {
        if (loginView != null) {
            loginView.setPasswordError();
            loginView.hideProgress();
        }
    }

    @Override
    public void onSuccess() {
        if (loginView != null) {
            loginView.navigateToHome();
        }
    }
}

validateCredentials这个方法看上去很熟悉,如果看的仔细的同学应该记得Activity中通过Presenter对象在登录按钮触发函数中调用了这个方法,这个Activity的核心功能就在这个方法里面实现的,这个方法

MainActivity.java

   public void validateCredentials(String username, String password) {
        if (loginView != null) {
            loginView.showProgress();
        }

        loginInteractor.login(username, password, this);
    }

这个方法里面调用了loginInteractor这个接口的登录方法,同时在类中还实现了这个接口的三个方法,我们看看这个loginInteractor接口的代码,它做了什么

LoginInteractor.java

public class LoginInteractor {

    interface OnLoginFinishedListener {
        void onUsernameError();

        void onPasswordError();

        void onSuccess();
    }

    public void login(final String username, final String password, final OnLoginFinishedListener listener) {
        // Mock login. I'm creating a handler to delay the answer a couple of seconds
        new Handler().postDelayed(() -> {
            if (TextUtils.isEmpty(username)) {
                listener.onUsernameError();
                return;
            }
            if (TextUtils.isEmpty(password)) {
                listener.onPasswordError();
                return;
            }
            listener.onSuccess();
        }, 2000);
    }

核心方法中的几种登录失败情况(密码和用户名为空)以及登录成功的情况都是调用了他自身的OnLoginFinishedListener这个接口中的三个方法,仔细想想,其实是在LoginPresenter中实现的这个三个方法,这三个方法 如示例 所示,都涉及了LoginView
的处理,最终的实现也是在Presenter这个类里面。

 @Override
    public void onUsernameError() {
        if (loginView != null) {
            loginView.setUsernameError();
            loginView.hideProgress();
        }
    }

整个过程因为是由上到下说的,有点绕,我们正向梳理一遍。

1.我们其实就可以感觉到MVP处理逻辑的一种用法,涉及到view,本例子中是进度条显示和隐藏,就放到view接口中,在Activity中绑定相关控件的ID,实现I对应的View接口中的方法。

2.涉及到最具体的处理的逻辑放在另外的一个类就是LoginInterctor(从名字上理解感觉是一种拦截器的命名方式,第二张接口图中MainActivity页面也是),这类中首先放的是一个接口OnLoginFinishedListener,剩下的放核心方法,核心方法login()调用自己的内部接口OnLoginFinishedListene具体的不同情况下方法。

3.最后回到Presenter中将view和interactor建立联系——构造函数就是,有了相关的view,剩下就是可以在这个类中实现interactotr类的接口中具体实现方法,核心方法validateCredentials()中调用interactor类中的核心方法login()就行。

4.最后,回到Activity中,我们只需要完成一个presenter的实例化过程,调用它最后的方法,就能实现MVP方式管理一个Activity
MainActivity中的道理一样,感兴趣的同学可以下载看看,可以加深理解。
https://github.com/antoniolg/androidmvp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值