爲什麼要進行MVP的二次深入封裝?
這裏我是參看了:《如何更高效的使用MVP以及官方MVP架構解析》,通過上面的學習弄了個登錄的demo,用於方便理解。
先來看看項目的文件
BasePresenter
如果每一個Activity都需要做綁定和解綁操作就太麻煩了,現在我希望可以有一個通用的presenter來爲我們添加view的綁定與銷燬。
public abstract class BasePresenter<T> {
public T mView;
public void attach(T view) {
this.mView = view;
}
public void dettach() {
mView = null;
}
}
因爲不能限定死傳入的View,所以使用泛型來代替傳入的對象。通過這個通用的presenter我就可以把LoginPresenter簡化成下面的樣子。(Presenter主要進行業務邏輯,事件監聽的處理,起(M層)
biz 與 (V層) activity之間的橋樑連接作用)
public class LoginPresenter extends BasePresenter<ILoginView> {
private final LoginBiziml loginBiziml;
private final Handler handler;
public LoginPresenter() {
loginBiziml = new LoginBiziml();
handler = new Handler();
}
public void toDoLogin() {
String userName = mView.getUserName();
String passWord = mView.getPassWord();
if (TextUtils.isEmpty(userName)) {
mView.showErrorMsg("用戶名不能爲空");
return;
}
if (TextUtils.isEmpty(passWord)) {
mView.showErrorMsg("密碼不能爲空");
return;
}
mView.showLoading();
User user = new User();
user.userName = userName;
user.passWord = passWord;
loginBiziml.loginApp(user, new OnLoginBizListener() {
@Override
public void onLoginSuccess(boolean isSuccess) {
handler.post(new Runnable() {
@Override
public void run() {
mView.hiddenLoading();
mView.showSuccessMsg("登錄成功");
}
});
}
@Override
public void onLoginFailed(boolean isSuccess) {
handler.post(new Runnable() {
@Override
public void run() {
mView.hiddenLoading();
mView.showErrorMsg("登錄失敗");
}
});
}
});
}
public void clear() {
mView.clearText();
}
}
BaseView界面需要提供的UI方法中會有很多類似的UI方法,可以把它們提取到一個公共的父類接口中。比如提取顯示loading界面和隱藏loading界面的方法等等,其他的view層接口就可以直接繼承BaseView接口,不必重複的寫顯示和隱藏loading界面方法。
public interface BaseView {
void showLoading();
void hiddenLoading();
void showSuccessMsg(String msg);
void showErrorMsg(String msg);
}
BaseActivity
presenter綁定到activity和View的綁定和解綁操作是每個Activity都會去做的,同樣這裏我也希望能有一個父類來完成這個統一的操作。
public abstract class BaseActivity<V,T extends BasePresenter<V>> extends AppCompatActivity {
public T presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = initPresenter();
}
@Override
protected void onResume() {
super.onResume();
presenter.attach((V) this);
}
@Override
protected void onDestroy() {
presenter.dettach();
super.onDestroy();
}
public abstract T initPresenter();
}
同樣使用泛型來提取通用的邏輯,presenter的初始化,以及view的綁定和解綁操作都提取到父類Activity中。向外部提供了一個 initPresenter(); 方法用來初始化presenter,如果想創建不同參數的構造函數都可以隨意去創建。
LoginActivity(我這裏寫demo時直接用MainActivity)
public class MainActivity extends BaseActivity<ILoginView, LoginPresenter> implements ILoginView {
private EditText mEtUsername, mEtPassword;
private Button mBtnLogin, mBtnClear;
private ProgressBar mPbLoading;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initview();
}
private void initview() {
mEtUsername = (EditText) findViewById(R.id.id_et_username);
mEtPassword = (EditText) findViewById(R.id.id_et_password);
mBtnClear = (Button) findViewById(R.id.id_btn_clear);
mBtnLogin = (Button) findViewById(R.id.id_btn_login);
mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading);
mBtnLogin.setOnClickListener(new View.OnClickListener() {
private User user;
@Override
public void onClick(View v) {
presenter.toDoLogin();
}
});
mBtnClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.clear();
}
});
}
@Override
public LoginPresenter initPresenter() {
return new LoginPresenter();
}
@Override
public void toMain() {
}
@Override
public void clearText() {
mEtUsername.setText(null);
mEtPassword.setText(null);
}
@Override
public String getUserName() {
return mEtUsername.getText().toString().trim();
}
@Override
public String getPassWord() {
return mEtPassword.getText().toString().trim();
}
@Override
public void showLoading() {
mPbLoading.setVisibility(View.VISIBLE);
}
@Override
public void hiddenLoading() {
mPbLoading.setVisibility(View.GONE);
}
@Override
public void showSuccessMsg(String msg) {
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
@Override
public void showErrorMsg(String msg) {
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
}
activity中只做了控件的初始化和展示,有沒有代碼很簡潔感覺,趕緊動手敲敲吧。