MVP模式 簡單介紹

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入門的介紹.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章