MVP示例圖
實現步驟簡單介紹
- 1.創建IPresenter接口,把所有業務邏輯的接口都放在這裏,並創建它的實現PresenterImpl(在這裏可以方便地查看業務功能,由於接口可以有多種實現所以也方便寫單元測試)
- 2.創建IView接口,把所有視圖邏輯的接口都放在這裏,其實現類是當前的Activity/Fragment
- 3.由UML圖可以看出,Activity裏包含了一個IPresenter,而PresenterCompl裏又包含了一個IView並且依賴了Model。Activity裏只保留對IPresenter的調用,其它工作全部留到PresenterCompl中實現
- 4.Model並不是必須有的,但是一定會有View和Presenter
1.創建ILoginView接口
視圖層要繼承此類(裏面的方法可以等到有需求的時候再添加)
//視圖邏輯的接口 public interface ILoginView { //清空文本 void onClearText(); //設置是否隱藏或者顯示 void onSetProgressBarVisiblity(int visible); //判斷是否登入 void onLogin(Boolean isLoginSuccess); }
2.創建ILoginPresenter接口
在視圖類中創建,實現該接口的實現類
//業務邏輯的接口 public interface ILoginPresenter { //清空 void clear(); //設置是否隱藏 void setProgressBarVisiblity(int visible); //判斷是否登入 void dologin(String name, String passWord); }
3.MainActivity的中的佈局和代碼
佈局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
>
<EditText
android:id="@+id/et_login_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="用戶名"/>
<EditText
android:id="@+id/et_login_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密碼"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_login_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="4dp"
android:layout_weight="1"
android:text="登入"/>
<Button
android:id="@+id/btn_login_clear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_weight="1"
android:text="取消"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="測試賬號:123 密碼:123"/>
<ProgressBar
android:id="@+id/progress_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"/>
</LinearLayout>
代碼
public class MainActivity extends AppCompatActivity implements ILoginView {
@BindView(R.id.et_login_username)
EditText mEtLoginUsername;
@BindView(R.id.et_login_password)
EditText mEtLoginPassword;
@BindView(R.id.btn_login_login)
Button mBtnLoginLogin;
@BindView(R.id.btn_login_clear)
Button mBtnLoginClear;
@BindView(R.id.progress_login)
ProgressBar mProgressLogin;
private ILoginPresenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
//創建LoginPresenterImpl類,傳入實現了ILoginView接口的類
mPresenter = new LoginPresenterImpl(this);
mPresenter.setProgressBarVisiblity(View.INVISIBLE);
}
//點擊事件
@OnClick({R.id.btn_login_login, R.id.btn_login_clear})
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_login_login:
//邏輯處理交給Presenter的實現類
mPresenter.setProgressBarVisiblity(View.VISIBLE);
mPresenter.dologin(mEtLoginUsername.getText().toString(), mEtLoginPassword.getText().toString());
break;
case R.id.btn_login_clear:
//先調用P層的clear方法,然後通過P層的裏的類,調用V層的onClearText()方法
//視圖的邏輯纔會在V層處理
mPresenter.clear();
break;
}
}
//清空文本欄
@Override
public void onClearText() {
mEtLoginUsername.setText("");
mEtLoginPassword.setText("");
}
//對進度條是否隱藏設置
@Override
public void onSetProgressBarVisiblity(int visible) {
mProgressLogin.setVisibility(visible);
}
@Override
public void onLogin(Boolean isLoginSuccess) {
mPresenter.setProgressBarVisiblity(View.INVISIBLE);
if (isLoginSuccess) {
Toast.makeText(this, "登入成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "登入失敗", Toast.LENGTH_SHORT).show();
}
}
}
Presenter的實現類LoginPresenterImpl的代碼
public class LoginPresenterImpl implements ILoginPresenter {
private Boolean isLoginSuccess;
//要持有實現ILoginView接口的引用
private ILoginView mILoginView;
private Handler mHandler = new Handler();
public LoginPresenterImpl(ILoginView iLoginView) {
mILoginView = iLoginView;
}
@Override
public void clear() {
mILoginView.onClearText();
}
@Override
public void setProgressBarVisiblity(int visible) {
mILoginView.onSetProgressBarVisiblity(visible);
}
@Override
public void dologin(String name, String passWord) {
if ("123".equals(name) && "123".equals(passWord)) {
isLoginSuccess = true;
} else {
isLoginSuccess = false;
}
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mILoginView.onLogin(isLoginSuccess);
}
}, 5000);
}
}
總結
MVP切斷的View和Model的聯繫,讓View只和Presenter(原Controller)交互,減少在需求變化中需要維護的對象的數量,更好的實現職責單一明確,方便項目後期擴展,後期會更新MVP入門的介紹.