前言
本文适合MVP初学者,这东西可以说你一天不写就手生。初学的时候肯定要多多写写,用不同的场景模拟以下MVP的实现逻辑。如果看不懂的话就从我的MVC笔记→MVP笔记先过一遍,我不能保证一定能看懂,但是个人觉得多写写,只要逻辑思维不错的话入门还是比较快的。
逻辑
用户输入用户名和密码点击登陆,然后按钮显示登录中,并针对各种情况作出提示。登陆成功则跳转到下一页面。老规矩先看分包:
逻辑层次不明白的我无FUCK说…
代码
仔细看这个逻辑的话其实是一个很简答的流程,那么我们从用户出发,他要做的事情就是输入用户名和密码然后点击登陆。他是和View进行交互的,那么我们先看View。
LoginView
public interface LoginView {
String getName();
String getPassword();
void uiChange();
void uiNormal();
void loginSuccess();
}
这里面呢,不是用户做的事情,而是整个程序要对View做的事情。也就是说,当用户输入用户名密码点击按钮以后,对于View来说,你要让它干点啥事儿。要干这么几件事,从View拿出账户名,拿出密码,然后登陆逻辑执行前,要做个登录中的效果显示出来,然后登陆逻辑结束后要恢复正常,在登陆成功以后要跳到下一个页面。这些操作都是针对View来做的,因为你Activity的布局文件本身也是一个View嘛。
然后拿出来以后要干嘛呢?登陆逻辑是在哪里进行的呢?要在Model,维森末呢?因为Model要做的事情是处理业务逻辑,啥是业务逻辑,简单来讲就是你用户不不需要知道的事情。比如你点击登陆你还要知道他是怎么登陆的呢?显然不需要,只要给你一个登陆成功或者失败的结果就OK。
LoginModel
public interface LoginModel {
void Login(String name, String password, Context context, OnLoginListener listener);
}
OnLoginListener
public interface OnLoginListener {
void beginLogin();
void successLogin();
void failedLogin();
}
LoginModelImp【延时操作模拟登录中效果】
public class LoginModelImp implements LoginModel {
@Override
public void Login(final String name, final String password, final Context context, final OnLoginListener listener) {
listener.beginLogin();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (AppUtils.isNotEmpty(name) && AppUtils.isNotEmpty(password)) {
Toast.makeText(context, "登陆成功", Toast.LENGTH_SHORT).show();
listener.successLogin();
} else {
if (AppUtils.isEmpty(name))
Toast.makeText(context, "姓名为空", Toast.LENGTH_SHORT).show();
if (AppUtils.isEmpty(password))
Toast.makeText(context, "密码为空", Toast.LENGTH_SHORT).show();
listener.failedLogin();
}
}
}, 2000);
}
}
这里如果你不懂为啥要加个监听的回调,你需要去学习接口回调与MVC入门。
然后的话就需要Presenter把这两个玩意儿连接起来。【PS:当你写这一步的时候,要想想怎么来设计这个流程更加合理而不是仅仅为了实现MVP去写它】
LoginPresenter
public class LoginPresenter {
private LoginView loginView;
private LoginModel loginModel;
public LoginPresenter(LoginView loginView) {
this.loginView = loginView;
this.loginModel = new LoginModelImp();
}
public void getInfoToLogin(String name, String password, Context context) {
loginModel.Login(name, password, context, new OnLoginListener() {
@Override
public void beginLogin() {
loginView.uiChange();
}
@Override
public void successLogin() {
loginView.uiNormal();
loginView.loginSuccess();
}
@Override
public void failedLogin() {
loginView.uiNormal();
}
});
}
}
在MainActivity中使用
public class MainActivity extends AppCompatActivity implements View.OnClickListener, LoginView {
private EditText etName;
private EditText etPassword;
private Button btnLogin;
private LoginPresenter loginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
initView();
loginPresenter = new LoginPresenter(this);
}
private void initView() {
etName = (EditText) findViewById(R.id.etName);
etPassword = (EditText) findViewById(R.id.etPassword);
btnLogin = (Button) findViewById(R.id.btnLogin);
btnLogin.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnLogin:
loginPresenter.getInfoToLogin(getName(), getPassword(), this);
break;
}
}
@Override
public String getName() {
return etName.getText().toString();
}
@Override
public String getPassword() {
return etPassword.getText().toString();
}
@Override
public void uiChange() {
etName.setEnabled(false);
etPassword.setEnabled(false);
btnLogin.setText("登录中...");
}
@Override
public void uiNormal() {
etName.setText("");
etPassword.setText("");
etName.setEnabled(true);
etPassword.setEnabled(true);
btnLogin.setText("登录");
}
@Override
public void loginSuccess() {
startActivity(new Intent(this, LoginedActivity.class));
overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
finish();
}
}
演示效果
结语
还是老话,不要懒,多写写很多东西自己就懂了,中国有一句老话说书读百遍其义自见也是这个理儿。至于代码的话= =兄弟们我还不会用GIT不要鄙视我- -不懂也不能装懂。后期我学会以后就把这些demo上传到github上去。