Android 从零搭建简单MVP Demo
首先简单介绍一下MVP的构成及优缺点:
MVP的全称为Model-View-Presenter,
Model提供数据(网络请求、数据存储等);
View负责页面显示;
Presenter负责逻辑的处理;
优点:主要就是将Model层和View层完全解耦,使得两者任一方的修改都不会对另一方产生影响,而是将逻辑处理放在了Presenter层;
缺点:显而易见,随着项目的增大,Presenter层也会变得臃肿,所以根据不同项目逻辑灵活的去使用Presenter也很重要;
之前有做过基于MVP的Android项目,根据别人写好的结构,无非就是填充代码,对于MVP整体的理解不够到位,所以该如何从头去理解一个MVP项目,对今后避免一些逻辑错误也是至关重要的。
下面我会以简单的登录模块为例,结合具体代码将整个MVP分步来构建,以便更好的去理解MVP,有需要的可以将完整demo去文末clone下来。
1.定义View层接口
public interface LoginView { void showProgress(); void hideProgress(); void loginSuccess(); void loginFail(); }
2.LoginActivity实现View接口,基本页面布局就不一一展示了,只附上关键代码
LoginActivity ->
@Override public void showProgress() { mWaitLogin.setVisibility(View.VISIBLE); } @Override public void hideProgress() { mWaitLogin.setVisibility(View.GONE); } @Override public void loginSuccess() { Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show(); //登录成功,跳转到主页面 } @Override public void loginFail() { Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show(); //登录失败,停留在登录页面 }
3.定义Model接口
public interface LoginModel { interface OnLoginListener { void onLoginSuccess(); void onLoginFail(); } void login(String username, String password, OnLoginListener listener); }
4.实现Model接口,模拟登录请求
public class LoginModelImpl implements LoginModel { @Override public void login(final String username, final String password, final OnLoginListener listener) { new Handler().postDelayed(new Runnable() { @Override public void run() { if (username.equals("1") && password.equals("1")) { listener.onLoginSuccess(); } else { listener.onLoginFail(); } } }, 3000); } }
5.这时我们需要知道,在LoginActivity中点击登录后,需要通过Presenter去控制Model来执行具体登录操作,所以接下来定义Presenter接口
public interface LoginPresent { void doLogin(String username, String password); }
6.实现Presenter接口,编写具体的逻辑
public class LoginPresentImpl implements LoginPresent,LoginModel.OnLoginListener{ private LoginView mView; private LoginModel mModel; public LoginPresentImpl(LoginView view, LoginModel model) { mView = view; mModel = model; } @Override public void doLogin(String username,String password) { mView.showProgress(); mModel.login(username, password, this); } @Override public void onLoginSuccess() { mView.hideProgress(); mView.loginSuccess(); } @Override public void onLoginFail() { mView.hideProgress(); mView.loginFail(); } }
7.在LoginActivity中控制Presenter去进行登录处理
mPresent = new LoginPresentImpl(this, new LoginModelImpl()); mLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String username = mUserName.getText().toString().trim(); String password = mPassword.getText().toString().trim(); //简单进行非空验证 if (username != null && !username.equals("") && password != null && !password.equals("")) { //这里想要执行登录操作,需要通过Present控制Model请求 mPresent.doLogin(username, password); } else { Toast.makeText(LoginActivity.this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show(); } } });
麻雀虽小,五脏俱全,这样一个完整的MVP模式就一步一步构建出来了。