MVP merupakan singkatan dari Model-View-Presenter. MVP adalah arsitektur atau design pattern yang memisahkan antara proses bisnis dan logic di luar dari Activity dan Fragment serta membuatnya menjadi lifecycle tersendiri. Dengan menggunakan arsitektur MVP dapat membuat pengembangan aplikasi Android yang kompleks jadi lebih mudah dan simpel, jumlah kode program menjadi lebih sedikit serta mudah di maintenance.
Berikut penjelasan dari masing-masing layer di MVP :
View : Layer ini merupakan layer untuk menampilkan data dan interaksi ke user. View biasanya ditempatkan di Activity, Fragment atau Dialog di Android.
Model : Layer ini merupakan layer untuk mengakses data dari local maupun remote server.
Presenter : Layer ini merupakan layer yang menjembatani antara Model dan View. Presenter juga dapat berjalan di background task.
Pada kesempatan kali ini, kita akan coba membuat sebuah aplikasi dengan arsitektur MVP.
Buat project baru kemudian buat sistem package seperti berikut :
Pertama kali kita membuat layout terlebih dahulu. Di sini kita akan membuat dua buah layout diantaranya :
1. activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/activity_vertical_margin">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:padding="@dimen/activity_horizontal_margin">
<EditText
android:id="@+id/et_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/email_hint"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/password_hint"
android:inputType="textPassword" />
</LinearLayout>
<Button
android:text="@string/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="loginAct"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
2. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>Selanjutnya kita akan membuat kerangka Model-View-Presenter.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.wimsonevel.androidmvp.MainActivity">
<TextView
android:id="@+id/tv_welcome"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/welcome"
android:textSize="24sp" />
<TextView
android:id="@+id/tv_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_welcome"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="12dp" />
</RelativeLayout>
Model
Buat package dengan nama model, kemudian buat kelas java dengan nama User.java
package com.wimsonevel.androidmvp.model;View
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by Wim on 12/31/16.
*/
public class User implements Parcelable {
private String email;
public User(String email) {
this.email = email;
}
protected User(Parcel in) {
this.email = in.readString();
}
public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
@Override
public User createFromParcel(Parcel source) {
return new User(source);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.email);
}
}
Buat package dengan nama view, kemudian buat beberapa interface view berikut :
BaseView.java
package com.wimsonevel.androidmvp.view;LoginView.java
import android.content.Context;
/**
* Created by Wim on 12/31/16.
*/
public interface BaseView {
Context getContext();
}
package com.wimsonevel.androidmvp.view;
import com.wimsonevel.androidmvp.model.User;
/**
* Created by Wim on 1/1/17.
*/
public interface LoginView extends BaseView {
void onSuccess(User user);
void onFailed(String msg);
void showProgress();
void hideProgress();
}
Presenter
Buat package dengan nama presenter, kemudian buat beberapa kelas presenter berikut :
BasePresenter.java
package com.wimsonevel.androidmvp.presenter;LoginPresenter.java
/**
* Created by Wim on 12/31/16.
*/
public interface BasePresenter<V> {
void attachView(V view);
void detachView();
boolean isViewAttached();
}
package com.wimsonevel.androidmvp.presenter;
import com.wimsonevel.androidmvp.R;
import com.wimsonevel.androidmvp.model.User;
import com.wimsonevel.androidmvp.view.LoginView;
/**
* Created by Wim on 1/1/17.
*/
public class LoginPresenter implements BasePresenter<LoginView> {
private LoginView loginView;
@Override
public void attachView(LoginView view) {
this.loginView = view;
}
@Override
public void detachView() {
this.loginView = null;
}
@Override
public boolean isViewAttached() {
return loginView != null;
}
public void doLogin(String email, String password) {
loginView.showProgress();
if(email.equals("example@mail.com") && password.equals("wim")) {
loginView.hideProgress();
loginView.onSuccess(new User(email));
}else{
loginView.hideProgress();
loginView.onFailed(loginView.getContext().getResources().getString(R.string.login_failed));
}
}
}
Activity
Selanjutnya adalah membuat beberapa activity sebagai berikut :
LoginActivity.java
package com.wimsonevel.androidmvp;MainActivity.java
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.wimsonevel.androidmvp.model.User;
import com.wimsonevel.androidmvp.presenter.LoginPresenter;
import com.wimsonevel.androidmvp.view.LoginView;
import static android.text.TextUtils.isEmpty;
/**
* Created by Wim on 1/1/17.
*/
public class LoginActivity extends AppCompatActivity implements LoginView {
private EditText etEmail;
private EditText etPassword;
private LoginPresenter loginPresenter;
private ProgressDialog progressDialog;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
etEmail = (EditText) findViewById(R.id.et_email);
etPassword = (EditText) findViewById(R.id.et_password);
progressDialog = new ProgressDialog(this);
progressDialog.setMessage(this.getResources().getString(R.string.loading));
}
void loginAct(View view) {
loginPresenter = new LoginPresenter();
loginPresenter.attachView(this);
if(isEmpty(etEmail.getText().toString())) {
return;
}
if(isEmpty(etPassword.getText().toString())) {
return;
}
if(loginPresenter.isViewAttached()) {
loginPresenter.doLogin(etEmail.getText().toString(), etPassword.getText().toString());
}
}
@Override
public void onSuccess(User user) {
Toast.makeText(this, this.getResources().getString(R.string.login_success), Toast.LENGTH_SHORT).show();
MainActivity.start(this, user);
}
@Override
public void onFailed(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
@Override
public void showProgress() {
progressDialog.show();
}
@Override
public void hideProgress() {
progressDialog.dismiss();
}
@Override
public Context getContext() {
return this;
}
@Override
protected void onDestroy() {
super.onDestroy();
loginPresenter.detachView();
}
}
package com.wimsonevel.androidmvp;Terakhir beberapa tambahan resource string di strings.xml
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import com.wimsonevel.androidmvp.model.User;
public class MainActivity extends AppCompatActivity {
private TextView tvEmail;
public static void start(Context context, User user) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(MainActivity.class.getSimpleName(), user);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvEmail = (TextView) findViewById(R.id.tv_email);
User user = getIntent().getParcelableExtra(MainActivity.class.getSimpleName());
tvEmail.setText(user.getEmail());
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
<resources>Build dan running maka hasilnya seperti berikut :
<string name="app_name">Android-MVP-Pattern</string>
<string name="email_hint">Email</string>
<string name="password_hint">Password</string>
<string name="login">Login</string>
<string name="welcome">Welcome</string>
<string name="login_success">Login Success!</string>
<string name="login_failed">Incorrect username or password!</string>
<string name="loading">Loading...</string>
</resources>
Source code lengkap dapat di download di https://github.com/wimsonevel/Android-MVP-Pattern
Sekian tutorial kali ini.
Semoga bermanfaat :)