1、模型与视图完全分离,我们可以修改视图而不影响模型
2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部
3、我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)
下面示例一个小案例:
项目架构:
首先bean层:
User.java
public class User { private String username; private String password; public String getUsername() { return username; } public String getPassword() { return password; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } }
MainActivity.java
public class MainActivity extends AppCompatActivity implements IUserLoginView{ private EditText musername; private EditText mpasssword; private Button mlogin; private Button mclear; private ProgressBar mpb; private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { musername = (EditText) findViewById(R.id.username); mpasssword = (EditText) findViewById(R.id.password); mlogin = (Button)findViewById(R.id.login); mclear = (Button)findViewById(R.id.clear); mpb = (ProgressBar) findViewById(R.id.pb); mlogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mUserLoginPresenter.login(); } }); mclear.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mUserLoginPresenter.clear(); } }); } @Override public String getUsername() { return musername.getText().toString(); } @Override public String getPassword() { return mpasssword.getText().toString(); } @Override public void clearUsername() { musername.setText(""); } @Override public void clearPassword() { mpasssword.setText(""); } @Override public void showLoading() { mpb.setVisibility(View.VISIBLE); } @Override public void hideLoading() { mpb.setVisibility(View.GONE); } @Override public void toMainActivity(User user) { Toast.makeText(this, user.getUsername() + " login success , to MainActivity", Toast.LENGTH_SHORT).show(); } @Override public void showFailError() { Toast.makeText(this, "login failed", Toast.LENGTH_SHORT).show(); } }
IUserLoginView.java
public interface IUserLoginView { //操作的目的 String getUsername(); String getPassword(); void clearUsername(); void clearPassword(); //友好的交互 void showLoading(); void hideLoading(); //操作的结果,对应的反馈 void toMainActivity(User user); void showFailError(); }
UserLoginPresenter.java
//Model和View的桥梁 login clear public class UserLoginPresenter { private IUserLoginView userLoginView; private IUserBiz userBiz; private Handler mHandler = new Handler(); public UserLoginPresenter(IUserLoginView userLoginView){ this.userLoginView = userLoginView; this.userBiz = new UserBiz(); } public void login() { userLoginView.showLoading(); userBiz.login(userLoginView.getUsername(), userLoginView.getPassword(),new OnLoginListener() { @Override public void loginsuccess(final User user) { //需要在UI线程执行 mHandler.post(new Runnable() { @Override public void run() { userLoginView.toMainActivity(user); userLoginView.hideLoading(); } }); } @Override public void loginfail() { //需要在UI线程执行 mHandler.post(new Runnable() { @Override public void run() { userLoginView.showFailError(); userLoginView.hideLoading(); } }); } }); } public void clear() { userLoginView.clearUsername(); userLoginView.clearPassword(); } }
IUserBiz.java
public interface IUserBiz { public void login(String username,String password,OnLoginListener loginListener); }
UserBiz.java
public class UserBiz implements IUserBiz { @Override public void login(final String username,final String password, final OnLoginListener loginListener) { new Thread(){ @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } if("name".equals(username)&&"pwd".equals(password)){ User user = new User(); user.setUsername(username); user.setPassword(password); loginListener.loginsuccess(user); }else{ loginListener.loginfail(); } } }.start(); } }
OnLoginListener.java
public interface OnLoginListener { void loginsuccess(User user); void loginfail(); }