Introduction
MVP stands for Model View Presenter. This pattern is a derivate from MVC, i.e., Model View Controller.
MVP pattern allows separation of presentation layer from the logic. It is not an architectural pattern, It is only responsible for the presentation layer. This pattern useful for large applications where the code is well organized.
Benefits Of Using MVP
By using MVP, separation of the data source and individuals view is possible. This logic could be taken out of activities. Hence testing can be accomplished without Instrumentation test.
Collaboration Of Different Layers With MVP Pattern.
Presenter
The Presenter is a bridge between the View and Model. It is s hub for all presentation logic. It fetches and transform the data from the model to update the view or tells the view when to update.
View
The View component contains visual part of the application, in other words, it is an Activity or Fragment that contains only UI and not any logic. It contains a reference to the presenter. It presents the data in a way decided by the presenter. Whenever there is an interface action like updateData, showProgressBar, buttonClick, etc., View calls for a method from the Presenter.
Model
The model contains the data provider and the code. This code manages to fetch and update the data. It also updates the database and communicates with the web server. The model’s responsibility includes
- Using API’s
- Manage Database
- Caching data
- It works as a gateway to the domain layer and business logic
This is all about the different layers of MVP pattern. Let’s see how we can follow this pattern with a simple example.
Example of code
Here, we will create an application which shows the Login screen after validating the data. Upon successful login, it opens the home screen which shows the list of items retrieved from the model.
- Create an Application MVPPatternExampleAndroid in Android Studio with an updated
- Create two packages one for Login and another for Main.
Requirements
Inside the package, Login Create an Activity for Login LoginActivity.java and activity_login.xml file, LoginPresenter interface and its class which implements this interface LoginPresenterImpl, LoginInteractor interface and its class which implements this interface LoginInteractorImpl, and LoginView interface.
Inside the package, Main Create an Activity for Home screen MainActivity.java and activity_main.xml file, MainPresenter interface and its class which implements this interface MainPresenterImpl, FindItemsInteractor interface and its class which implements this interface FindItemsInteractorImpl, and MainView interface.
All of these actions are conducted one after the other
activity_login.xml
Create XML file for login details. Here, we add EditText’s, Button for login and ProgressBar.
Add the code here
<EditText android:id="@+id/ed_Username" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:hint="@string/user_name" android:drawableLeft="@drawable/ic_action_person" android:drawablePadding="8dp" /> <EditText android:id="@+id/ed_Password" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:hint="@string/password" android:inputType="textPassword" android:drawableLeft="@drawable/ic_action_accounts" android:drawablePadding="8dp" /> <Button android:id="@+id/btn_Login" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/log_in" android:drawableRight="@drawable/ic_action_accept" /> <ProgressBar android:id="@+id/progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:visibility="gone" />
activity_main.xml
This is our Home screen which shows the list of items. Here, we add ListView and ProgressBar.
Add the code here
<ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" android:clipToPadding="false" android:scrollbarStyle="outsideOverlay" /> <ProgressBar android:id="@+id/progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="gone" />
LoginActivity.java
Create this Activity for Login and validating credentials. Here, view events are passed to the presenter. It implements LoginView.
Initialize
private ProgressBar progressBar; private EditText edUsername; private EditText edPassword; private LoginPresenter presenter;
Add the code in onCreate()
progressBar = (ProgressBar) findViewById(R.id.progress); edUsername = (EditText) findViewById(R.id.ed_Username); edPassword = (EditText) findViewById(R.id.ed_Password); findViewById(R.id.btn_Login).setOnClickListener(this); presenter = new LoginPresenterImpl(this);
Add the code to different events and click listener.
@Override public void showProgress() { progressBar.setVisibility(View.VISIBLE); } @Override public void hideProgress() { progressBar.setVisibility(View.GONE); } @Override public void setUsernameError() { edUsername.setError(getString(R.string.username_error)); } @Override public void setPasswordError() { edPassword.setError(getString(R.string.password_error)); } @Override public void navigateToHome() { startActivity(new Intent(this, MainActivity.class)); finish(); } @Override public void onClick(View v) { presenter.validateCredentials(edUsername.getText().toString(), edPassword.getText().toString()); }
LoginPresenter:
Create this interface in your project under Login package.
Add the code here:
void validateCredentials(String username, String password); void onDestroy();
LoginPresenterImpl.java
Create this java class here it implements LoginPresenter and LoginInteractor.OnLoginFinishedListener interface for updating the view. Here, presenter calls use cases handler, i.e., interactor.
Add the code here
Initialize
private LoginView loginView; private LoginInteractor loginInteractor;
Now implement the methods to validate the credentials.
@Override public void validateCredentials(String username, String password) { if (loginView != null) { loginView.showProgress(); } loginInteractor.login(username, password, this); } @Override public void onUsernameError() { if (loginView != null) { loginView.setUsernameError(); loginView.hideProgress(); } } @Override public void onPasswordError() { if (loginView != null) { loginView.setPasswordError(); loginView.hideProgress(); } } @Override public void onSuccess() { if (loginView != null) { loginView.navigateToHome(); } }
LoginInteractor
Create this interface in your project under Login package.
Add the code here
interface OnLoginFinishedListener { void onUsernameError(); void onPasswordError(); void onSuccess(); } void login(String username, String password, OnLoginFinishedListener listener);
LoginInteractorImpl.java
Create this class which implements LoginInteractor. Here, we define the method which is called from the presenter.
Add the code here
@Override public void login(final String username, final String password, final OnLoginFinishedListener listener) { new Handler().postDelayed(new Runnable() { @Override public void run() { boolean error = false; if (TextUtils.isEmpty(username)){ listener.onUsernameError(); error = true; return; } if (TextUtils.isEmpty(password)){ listener.onPasswordError(); error = true; return; } if (!error){ listener.onSuccess(); } } }, 2000); }
LoginView
Create this interface in your project under Login package. Here, presenter updates the view through this interface.
Add the code here
void showProgress(); void hideProgress(); void setUsernameError(); void setPasswordError(); void navigateToHome();
These events are handled in LoginActivity.
Similarly, we can also do for our Home screen which shows the list of items.
Output
Conclusion
Thus we have showcased a simple example of MVP pattern in Android. By using this, we can maintain the code in a well-formed manner mainly for large applications. It separates the activities from model classes and adapters etc. It keeps a project clean and testable. It increases the reliability of the application up to 10 times making the application code shorter and easy to test. Therefore this is a best practice to create an Android application, and it is very popular and important in Android development.