首先簡單介紹一下MVP的構成及優缺點:git
MVP的全稱爲Model-View-Presenter,github
Model提供數據(網絡請求、數據存儲等);網絡
View負責頁面顯示;ide
Presenter負責邏輯的處理;佈局
優勢:主要就是將Model層和View層徹底解耦,使得二者任一方的修改都不會對另外一方產生影響,而是將邏輯處理放在了Presenter層;post
缺點:顯而易見,隨着項目的增大,Presenter層也會變得臃腫,因此根據不一樣項目邏輯靈活的去使用Presenter也很重要;this
以前有作過基於MVP的Android項目,根據別人寫好的結構,無非就是填充代碼,對於MVP總體的理解不夠到位,因此該如何從頭去理解一個MVP項目,對從此避免一些邏輯錯誤也是相當重要的。spa
下面我會以簡單的登陸模塊爲例,結合具體代碼將整個MVP分步來構建,以便更好的去理解MVP,有須要的能夠將完整demo去文末clone下來。code
1.定義View層接口blog
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模式就一步一步構建出來了。