Android MVP 的入门级体验

来源:互联网 发布:手机域名注册管理局 编辑:程序博客网 时间:2024/06/06 20:27

    并没有在项目中用过MVP模式。看着网上一大堆MVP+Rxjava+Retrofit就发憷啊喂!头疼之后决定先顺着从mvp开始看起。


如果还有什么能支撑我学习,我想那就是贫穷了。。。

原教程在此


MVP概述

    MVP,全称Model(实体模型,用来提供数据)-View(对应于布局文件,单纯的展示数据)-Presenter(负责完成View与Model间的交互)。

    关于MVP---


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

Model与View不能直接交互,而是使用Presenter作为View与Model之间的桥梁。其中Presenter中同时持有View层的Interface的引用以及Model层的引用,而View层持有Presenter层引用。

当View层某个界面需要展示某些数据的时候,首先会调用Presenter层的引用,然后Presenter层会调用Model层请求数据,当Model层数据加载成功之后会调用Presenter层的回调方法通知Presenter层数据加载情况,最后Presenter层在调用View层的接口将加载后的数据展示给用户。

以上,都是抄的。



 用MVP写个登陆

入门的结构图如下



Model层

 Model层负责拿到账号密码之后请求接口进行登录验证。

User--实体类bean


public class User {    private String userName;    private String userPass;    public User() {    }    public User(String userName, String userPass) {        this.userName = userName;        this.userPass = userPass;    }    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }    public String getUserPass() {        return userPass;    }    public void setUserPass(String userPass) {        this.userPass = userPass;    }


 LoginModel--Model层的接口,其中OnLoginFinishedListener是Presenter层的接口,方便实现回调Presenter业务逻辑的返回结果

public interface LoginModel {    void login(User user, OnLoginFinishedListener listener);}

LoginModelImpl--Model层的接口

public class LoginModelImpl implements LoginModel {    @Override    public void login(User user, final OnLoginFinishedListener listener) {        final String username = user.getUserName();        final String password = user.getUserPass();        new Thread(new Runnable() {            @Override            public void run() {          //总而言之就是在这里请求接口 然后              if(验证用户名密码成功){                    listener.onSuccess();                }else if(不成功){                    listener.onFailure();               }               }).start();    }}


View层

视图:将Model曾请求的数据呈现给用户。在这里就是绘制好界面,写好不同情况对应的接口,等着被Presenter调用就好了。

LoginView--View层的接口

public interface LoginView {    //操作显示隐藏progress的方法    void showProgress();    void hideProgress();    //登陆失败    void showFailure();//登陆失败    //登陆成功    void showSuccess();}

LoginActivity--View层的接口实现类,需要实现LoginView接口

public class LoginActivity extends BaseActivity implements LoginView {    @BindView(R.id.login_et_userName)    EditText loginEtUserName;    @BindView(R.id.login_et_passWord)    EditText loginEtPassWord;    @BindView(R.id.login_iv_look)    CheckBox loginIvLook;    private LoginPresenter presenter;    @Override    protected void initView() {        setContentView(R.layout.activity_login);        ButterKnife.bind(this);        //创建一个presenter对象,当点击登录按钮时,        // 让presenter去调用model层的login()方法,验证帐号密码        presenter = new LoginPresenterImpl(this);        Info.isPassWordLook(loginEtPassWord, loginIvLook);// 进行明密码或者暗文密码的选择操作    }    @OnClick({R.id.login_iv_clear, R.id.login_btn_login, R.id.login_tv_register, R.id.login_tv_forget})    public void onViewClicked(View view) {        switch (view.getId()) {            case R.id.login_iv_clear://清空                loginEtUserName.setText("");                break;            case R.id.login_btn_login://登陆                String userName = loginEtUserName.getText().toString();                String userPass = loginEtPassWord.getText().toString();                if (Info.isEmptyOrNullString(userName)) {                    loginEtUserName.setError("用户名不能为空");                } else if (Info.isEmptyOrNullString(userPass)) {                    loginEtPassWord.setError("密码不能为空");                } else if (!Info.isPassword(userPass)) {                    loginEtPassWord.setError("密码应由6-20位英文字母、数字或符号组成。");                } else {                    User user = new User();                    user.setUserPass(userPass);                    user.setUserName(userName);                    presenter.validateCredentials(user);                }                break;            case R.id.login_tv_register://注册                showToast("注册");                break;            case R.id.login_tv_forget://忘记密码                showToast("忘记密码");                break;        }    }    /**     * 显示等待框     */    @Override    public void showProgress() {        showProgressDialog();    }    /**     * 隐藏等待框     */    @Override    public void hideProgress() {        closeProgressDialog();    }    @Override    public void showFailure() {        loginEtPassWord.setError("用户名或密码错误");    }    @Override    public void showSuccess() {        showToast("登陆成功");    }    @Override    protected void onDestroy() {        presenter.onDestroy();        super.onDestroy();    }}


Presenter层

Presenter是用作Model和View之间的桥梁。

OnLoginFinishedListener--Presenter层的接口,当Model层请求到结果,需要回调Presenter层让Presenter层调用View层的接口方法。

public interface OnLoginFinishedListener {    //登陆失败    void onFailure();//登陆失败    //登陆成功    void onSuccess();}

LoginPresenter--登陆的Presenter的接口,实现类为LoginPresenterImpl,完成登录的验证,以及销毁当前view

public interface LoginPresenter {//    验证凭据    void validateCredentials(User user);//销毁当前view    void onDestroy();}

LoginPresenterImpl--Presenter接口实现类,由于presenter完成二者的交互,那么肯定需要二者的实现类(通过传入参数,或者new)


public class LoginPresenterImpl implements LoginPresenter, OnLoginFinishedListener {    private LoginView loginView;//view层的接口    private LoginModel loginModel;//model层的接口    public LoginPresenterImpl(LoginView loginView) {        this.loginView = loginView;        this.loginModel = new LoginModelImpl();    }    @Override    public void validateCredentials(User user) {        if (loginView != null) {            loginView.showProgress();        }        loginModel.login(user, this);    }    @Override    public void onDestroy() {        loginView = null;    }    @Override    public void onFailure() {        if (loginView != null) {            loginView.showFailure();            loginView.hideProgress();        }    }    @Override    public void onSuccess() {        if (loginView != null) {            loginView.showSuccess();            loginView.hideProgress();        }    }}



就是这样~

1 0
原创粉丝点击