Advanced Android's MVP

Brief introduction

MVP stands for: Model-View-Presenter; MVP is evolved from the classic MVC pattern from, their basic ideas have in common places: Handling Controller / Presenter responsible for logic, Model provides data, View is responsible for displaying.

design diagram

advantage

1, M and V are completely separated, the coupling is reduced.
2, it can be used more efficiently Model, because all interactions are occurring within Presenter.
3, (Presener multiplexing) may be used for a plurality of views Presener (View), without changing the logical Presenter. Change the view (View) more frequently than change model (Model), it is so super convenient.
4, (View multiplexing) View of the components may be performed. Among the MVP, View not rely Model. This allows View spun off from a particular business scenario, it can be said View can be done on the business logic completely ignorant. It only needs to provide a range of interface to the upper layer operation. View so that you can make highly reusable components.
5, unit test easier.

Shortcoming

1, due to the rendering views on the Presenter, the View and Presenter view so that interaction would be too frequent. Especially in view of the need to modify the time, Presenter also need to follow the changes, a lot of trouble.
2, Presenter in addition to business logic, there are a lot of View-> Model, Model-> View the manual synchronization logic, resulting Presenter relatively heavy, it would be more difficult to maintain.
3, in fact, the whole structure is very clear, very clear business logic, low coupling, but it is to write their own troubles, Presenter bad maintenance, the workload is too big, too heavy, a bit like in MVC Activity, and responsibilities Too much.

Examples

1, Code

LoginInteractor.java


import android.os.Handler;
import android.text.TextUtils;

/**
 * Created on 2019/4/1 16:11
 *
 * @author Gong
 */
public class LoginInteractor {
    private Handler mHandler = new Handler();
    interface OnLoginFinishedListener{
        void onUsernameError();

        void onPasswordError();

        void onSuccess();
    }

    public void login(final String username, final String password, final OnLoginFinishedListener listener) {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (TextUtils.isEmpty(username)) {
                    listener.onUsernameError();
                    return;
                }
                if (TextUtils.isEmpty(password)) {
                    listener.onPasswordError();
                    return;
                }
                listener.onSuccess();
            }
        },2000);
    }
}

**LoginView.java**

<pre style="margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important; font-size: inherit; color: inherit; line-height: inherit;">

/**
 * Created on 2019/4/1 16:08
 *
 * @author Gong
 */
public interface LoginView {
    void showProgress();

    void hideProgress();

    void setUserNameError();

    void setPasswordError();

    void navigateToHome();
}

**LoginPresenter.java**

<pre style="margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important; font-size: inherit; color: inherit; line-height: inherit;">

/**
 * Created on 2019/4/1 16:19
 *
 * @author Gong
 */
public class LoginPresenter implements LoginInteractor.OnLoginFinishedListener {
    private LoginView mLoginView;
    private LoginInteractor mLoginInteractor;

    public LoginPresenter(LoginView loginView,LoginInteractor loginInteractor) {
        this.mLoginView = loginView;
        this.mLoginInteractor = loginInteractor;
    }

    public void validateCredentials(String username,String password) {
        if (mLoginView != null) {
            mLoginView.showProgress();
        }

        mLoginInteractor.login(username,password,this);
    }

    public void onDestroy() {
        mLoginView = null;
    }

    @Override
    public void onUsernameError() {
        if (mLoginView != null) {
            mLoginView.setUserNameError();
            mLoginView.hideProgress();
        }
    }

    @Override
    public void onPasswordError() {
        if (mLoginView != null) {
            mLoginView.setPasswordError();
            mLoginView.hideProgress();
        }
    }

    @Override
    public void onSuccess() {
        if (mLoginView != null) {
            mLoginView.navigateToHome();
        }
    }
}

LoginActivity.java


public class LoginActivity extends AppCompatActivity implements LoginView {
    private ProgressBar mProgressBar;
    private EditText mUserName,mPassword;
    private LoginPresenter mPresenter;
    private Button mLogin;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        initView();

        mPresenter = new LoginPresenter(this,new LoginInteractor());

        mLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                validateCredentials();
            }
        });

    }

    private void initView() {
        mPassword = findViewById(R.id.password);
        mUserName = findViewById(R.id.username);
        mProgressBar = findViewById(R.id.progress);
        mLogin = findViewById(R.id.login);
    }

    private void validateCredentials() {
        mPresenter.validateCredentials(mUserName.getText().toString(),mPassword.getText().toString());
    }

    @Override
    public void showProgress() {
        mProgressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideProgress() {
        mProgressBar.setVisibility(View.GONE);
    }

    @Override
    public void setUserNameError() {
        mUserName.setError(getString(R.string.user_name_error));
    }

    @Override
    public void setPasswordError() {
        mPassword.setError(getString(R.string.password_error));
    }

    @Override
    public void navigateToHome() {
        Intent intent = new Intent(LoginActivity.this, MainActivity.class);
        startActivity(intent);
        finish();
    }

   @Override
    protected void onDestroy() {
        mPresenter.onDestroy();
        super.onDestroy();
    }
}

ic_username.xml


<?xml version="1.0" encoding="utf-8"?>
<vector android:height="24dp" android:tint="#666666"
    android:viewportHeight="24.0" android:viewportWidth="24.0"
    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#FF000000" android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>

ic_password.xml


<?xml version="1.0" encoding="utf-8"?>
<vector android:height="24dp" android:tint="#666666"
    android:viewportHeight="24.0" android:viewportWidth="24.0"
    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#FF000000" android:pathData="M12.65,10C11.83,7.67 9.61,6 7,6c-3.31,0 -6,2.69 -6,6s2.69,6 6,6c2.61,0 4.83,-1.67 5.65,-4H17v4h4v-4h2v-4H12.65zM7,14c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"/>
</vector>

strings.xml


    <string name="user_name">请输入用户名</string>
    <string name="password">请输入密码</string>
    <string name="log_in">登录</string>
    <string name="user_name_error">用户名输入错误</string>
    <string name="password_error">密码输入错误</string>

activity_login.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="250dp"
    android:layout_height="match_parent"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="16dp"
    android:gravity="center"
    android:orientation="vertical">

    <EditText
        android:id="@+id/username"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:drawablePadding="8dp"
        android:drawableStart="@drawable/ic_username"
        android:gravity="center_vertical"
        android:hint="@string/user_name"
        android:inputType="text"
        android:drawableLeft="@drawable/ic_username" />

    <EditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:drawablePadding="8dp"
        android:drawableStart="@drawable/ic_password"
        android:gravity="center_vertical"
        android:hint="@string/password"
        android:inputType="textPassword"
        android:drawableLeft="@drawable/ic_password" />

    <Button
        android:id="@+id/login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/log_in" />

    <ProgressBar
        android:id="@+id/progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:visibility="gone" />

</LinearLayout> 

2. renderings

image

For more information + interview Android development framework to share information click on the link to receive free

"Android Architect necessary to receive a free learning resources (architecture + video + interview thematic document study notes)"

Guess you like

Origin blog.csdn.net/Coo123_/article/details/93056721
MVP