android_mvp理解与代码示例

来源:互联网 发布:网络文件服务器搭建 编辑:程序博客网 时间:2024/05/22 03:08

Android MVP理解与代码示例

使用MVP之利

  • MVP将使逻辑与Activity分离,便于测试
  • 便于扩展与维护
  • 避免代码耦合

MVP各职责

  • P:M与V的中间人,被V调用
  • V:在android中通常被Activity或Fragment实现,拥有P的引用,与用户交互
  • M:提供与维护数据

github上的代码理解

P与V的接口

public interface LoginPresenter {    public void validateCredentials(String username, String password);}public interface LoginView {    public void showProgress();    public void hideProgress();    public void setUsernameError();    public void setPasswordError();    public void navigateToHome();}
  • P的接口被实例实现,被Activity调用
  • V的接口被Activity实现,供P调用

LoginPresenterImpl有已经实现的V引用,在Activity相应用户事件时会自动被调用。

public class LoginPresenterImpl implements LoginPresenter, OnLoginFinishedListener {    private LoginView loginView;    private LoginInteractor loginInteractor;    public LoginPresenterImpl(LoginView loginView) {        this.loginView = loginView;        this.loginInteractor = new LoginInteractorImpl();    }    @Override public void validateCredentials(String username, String password) {        loginView.showProgress();        loginInteractor.login(username, password, this);    }    @Override public void onUsernameError() {        loginView.setUsernameError();        loginView.hideProgress();    }    @Override public void onPasswordError() {        loginView.setPasswordError();        loginView.hideProgress();    }    @Override public void onSuccess() {        loginView.navigateToHome();    }}

LoginIteractor是用来验证用户名与密码,它有着LoginPresentImpl的引用

public class LoginInteractorImpl implements LoginInteractor {    @Override    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(new Runnable() {            @Override public void run() {                boolean error = false;                if (TextUtils.isEmpty(username)){                    listener.onUsernameError();                    error = true;                }                if (TextUtils.isEmpty(password)){                    listener.onPasswordError();                    error = true;                }                if (!error){                    listener.onSuccess();                }            }        }, 2000);    }}

Activity加载中实现了LoginView, 成为了V的实例,可供P调用

public class LoginActivity extends Activity implements LoginView, View.OnClickListener {    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 = (ProgressBar) findViewById(R.id.progress);        username = (EditText) findViewById(R.id.username);        password = (EditText) findViewById(R.id.password);        findViewById(R.id.button).setOnClickListener(this);        presenter = new LoginPresenterImpl(this);    }    @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();    }    @Override public void onClick(View v) {        presenter.validateCredentials(username.getText().toString(), password.getText().toString());    }}

阅读代码感悟

  • MVP不是设计模式,不是架构模式。是两种模式思想的体现
  • 一个类只做一件事,如PresentImp, LoginInteractorImpl, 被其它类引用,在合适的时候被调用
  • 面向接口编程,存储对接口的引用,使用实例初始化
  • Activity只实现View, 用来与用户交互

参考资料

  • 代码参考github
  • 概念参考:MVP for Android: how to organize the presentation layer
0 0
原创粉丝点击