Kali ini kita akan membahas tentang apa itu arsitektur MVP atau biasa disebut design pattern. Sebenernya ada banyak design pattern seperti MVP, MVVM, MVC, DAO, Singleton dan lain-lain, lantas apakah perbedaan dari masing–masing design pattern tersebut? Jawabannya adalah tergantung pada penggunaan dan efektifitas mana yang lebih baik digunakan. Namun yang akan kami bahas hanya mengenai MVP karena design pattern ini yang sering umum digunakan pada pengembangan aplikasi android.
Model-View-Presenter atau yang biasa disingkat menjadi MVP adalah sebuah konsep arsitektur pengembangan aplikasi yang memisahkan antara tampilan aplikasi dengan proses bisnis yang bekerja pada aplikasi. Arsitektur ini akan membuat pengembangan aplikasi kita menjadi lebih terstuktur, mudah di-test dan juga mudah di-maintain.
Berikut penjelasan masing-masing layer pada MVP.
Manfaat menggunakan MVP Arsitektur:
-Membuat code menjadi rapi dan mudah dibaca
-Memudahkan dalam pekerjaan team
-Memudahkan dalam perubahan code / refactoring
-Memudahakan dalam mencari dan menganalisa bug
-Mudah untuk ditesting
Komponen dari MVP, benarlah sebuah Model, View dan Presenter. Namun lebih detailnya pada sebuah Activity ada beberapa komponen class yang harus dibuat supaya kita bisa menerapkan paradigma MVP pada codingan kita.
Misalnya kalian mempunyai sebuah class, MainActivity, maka komponen2 Presenter yang harus dibuat adalah sebagai berikut :
Bagaimana implementasinya?
Berikut akan saja buat projek sederhana untuk contoh implementasinya beserta langkah-langkanya.
Struktur project yang kita buat nantinya akan seperti ini.
Sebelumnya masukkan terlebih dahulu library yang dibutuhkan.
dependencies {
implementation 'com.android.support:recyclerview-v7:27.1.1'
}
Pertama, kita buat project baru dengan nama androidmvpsample
Lalu kita Activity dengan nama MainActivity
Lalu pada activity_main.xml modifikasi seperti berikut
<?xml version='1.0' encoding='utf-8'?>
<RelativeLayout xmlns:android='http://schemas.android.com/apk/res/android'
xmlns:app='http://schemas.android.com/apk/res-auto'
xmlns:tools='http://schemas.android.com/tools'
android:layout_width='match_parent'
android:layout_height='match_parent'
android:orientation='vertical'
tools:context='.MainActivity'>
<android.support.v7.widget.RecyclerView
android:id='@+id/recycler_view'
android:layout_width='match_parent'
android:layout_height='match_parent'></android.support.v7.widget.RecyclerView>
<Button
android:id='@+id/button_add'
android:layout_width='wrap_content'
android:layout_height='wrap_content'
android:layout_alignParentBottom='true'
android:layout_centerHorizontal='true'
android:layout_marginBottom='16dp'
android:background='@color/colorPrimary'
android:textColor='@android:color/white'
android:text='Tambah'/>
</RelativeLayout>
Lalu, kita buat data model-nya dengan nama User.java
public class User {
private int id;
private String nama;
private String status;
private String pekerjaan;
private String noHp;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNama() {
return nama;
}
public void setNama(String nama) {
this.nama = nama;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getPekerjaan() {
return pekerjaan;
}
public void setPekerjaan(String pekerjaan) {
this.pekerjaan = pekerjaan;
}
public String getNoHp() {
return noHp;
}
public void setNoHp(String noHp) {
this.noHp = noHp;
}
}
Lalu , kita buat interface untuk view dengan nama MainView.java
public interface MainView {
void onLoad(List<User> users);
void onSave();
void onDelete();
void onUpdate();
}
lalu, kita buat interface untuk presenter dengan nama MainPresenter.java
public interface MainPresenter {
void save(User user);
void update(User user);
void delete(User user);
void load();
}
Lalu, kita buat class untuk implementasi dari MainPresenter.java dengan nama MainPresenterImpl.java
public class MainPresenterImpl implements MainPresenter {
private MainView mainView;
public MainPresenterImpl(MainView mainView) {
this.mainView = mainView;
}
@Override
public void save(User user) {
}
@Override
public void update(User user) {
}
@Override
public void delete(User user) {
}
@Override
public void load() {
}
}
setelah itu kita modifikasi MainPresenterImpl.java seperti berikut
public class MainPresenterImpl implements MainPresenter {
private MainView mainView;
private List<User> users = new ArrayList<>();
private int no = 4;
public MainPresenterImpl(MainView mainView) {
this.mainView = mainView;
init();
}
private void init() {
User user = new User();
user.setId(1);
user.setNama('Kristiawan Adi');
user.setNoHp('085330684114');
user.setPekerjaan('Java Programmer');
user.setStatus('Jomblo sejak lahir');
users.add(user);
User user1 = new User();
user1.setId(2);
user1.setNama('Bimo Joko');
user1.setNoHp('085474748888');
user1.setPekerjaan('IT Scurity');
user1.setStatus('Udah punya pacar tapi drama melulu');
users.add(user1);
User user2 = new User();
user2.setId(3);
user2.setNama('Dirga');
user2.setNoHp('085332423043');
user2.setPekerjaan('IT Security');
user2.setStatus('Udah punya pacar dan bentar lagi nikah');
users.add(user2);
}
@Override
public void save(User user) {
no++;
user.setId(no);
users.add(user);
mainView.onSave();
}
@Override
public void update(User user) {
for (User model : users){
if (model.getId() == user.getId()){
model.setNama(user.getNama());
model.setStatus(user.getStatus());
model.setPekerjaan(user.getPekerjaan());
model.setNoHp(user.getNoHp());
break;
}
}
mainView.onUpdate();
}
@Override
public void delete(User user) {
users.remove(user);
mainView.onDelete();
}
@Override
public void load() {
mainView.onLoad(users);
}
}
Lalu kita buat layout dengan nama item_view_user.xml
<?xml version='1.0' encoding='utf-8'?>
<LinearLayout xmlns:android='http://schemas.android.com/apk/res/android'
android:orientation='vertical' android:layout_width='match_parent'
android:layout_height='wrap_content'
android:padding='16dp'>
<TextView
android:id='@+id/nama'
android:layout_width='match_parent'
android:layout_height='wrap_content'
android:textSize='16dp'
android:textColor='@android:color/black'
android:textStyle='bold'
android:text='Nama'/>
<TextView
android:id='@+id/status'
android:layout_width='match_parent'
android:layout_height='wrap_content'
android:text='Status'/>
</LinearLayout>
Selanjutnya, kita buat class adapter untuk menampilkan list menggunakan recycler view dengan nama MainRecyclerAdapter.java
public class MainRecyclerAdapter extends RecyclerView.Adapter<MainRecyclerAdapter.ViewHolder> {
private List<User> users;
private OnCallbackListener listener;
public MainRecyclerAdapter(List<User> users) {
this.users = users;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view_user, parent, false));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
User user = users.get(position);
holder.textViewNama.setText(user.getNama());
holder.textViewStatus.setText(user.getStatus());
}
@Override
public int getItemCount() {
return users.size();
}
public void setOnCallbackListener(OnCallbackListener listener) {
this.listener = listener;
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView textViewNama;
TextView textViewStatus;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
textViewNama = itemView.findViewById(R.id.nama);
textViewStatus = itemView.findViewById(R.id.status);
}
@Override
public void onClick(View v) {
if (listener != null) {
listener.onClick(users.get(getAdapterPosition()));
}
}
}
public interface OnCallbackListener {
void onClick(User user);
}
}
lalu pada class MainActivity.java kita buat sebagai berikut kita implementasikan interface MainView pada MainActivity
public class MainActivity extends AppCompatActivity implements MainView {
private RecyclerView recyclerView;
private Button buttonAdd;
private MainRecyclerAdapter adapter;
private List<User> userList = new ArrayList<>();
private AppCompatDialog dialog;
private MainPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
presenter = new MainPresenterImpl(this);
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MainRecyclerAdapter(userList);
recyclerView.setAdapter(adapter);
buttonAdd = findViewById(R.id.button_add);
}
@Override
public void onLoad(List<User> users) {
}
@Override
public void onSave() {
}
@Override
public void onDelete() {
}
@Override
public void onUpdate() {
}
}
lalu kita buat layout dialog_input.xml seperti berikut
<?xml version='1.0' encoding='utf-8'?>
<LinearLayout xmlns:android='http://schemas.android.com/apk/res/android'
android:layout_width='match_parent'
android:layout_height='wrap_content'
android:orientation='vertical'
android:padding='10dp'>
<EditText
android:id='@+id/edittext_nama'
android:layout_width='match_parent'
android:layout_height='wrap_content'
android:hint='Nama' />
<EditText
android:id='@+id/edittext_nohp'
android:layout_width='match_parent'
android:layout_height='wrap_content'
android:hint='Nomor HP' />
<EditText
android:id='@+id/edittext_pekerjaan'
android:layout_width='match_parent'
android:layout_height='wrap_content'
android:hint='Pekerjaan' />
<EditText
android:id='@+id/edittext_status'
android:layout_width='match_parent'
android:layout_height='wrap_content'
android:hint='Status' />
<RelativeLayout
android:layout_width='match_parent'
android:layout_height='wrap_content'
android:layout_marginBottom='5dp'
android:layout_marginTop='40dp'>
<Button
android:id='@+id/button_save'
android:layout_width='wrap_content'
android:layout_height='wrap_content'
android:layout_alignParentTop='true'
android:layout_marginRight='16dp'
android:layout_toStartOf='@+id/button_cancel'
android:text='Simpan'
android:textAllCaps='false' />
<Button
android:id='@+id/button_cancel'
android:layout_width='wrap_content'
android:layout_height='wrap_content'
android:layout_alignParentEnd='true'
android:layout_alignParentTop='true'
android:text='Cancel'
android:textAllCaps='false' />
</RelativeLayout>
</LinearLayout>
Berikutnya kita modifikasi MainActivity dengan menambahkan dialog untuk input data, edit dan delete
Tambahkan 2 method dibawah ini:
public void showDialogInput() {
dialog = new AppCompatDialog(this);
dialog.setContentView(R.layout.dialog_input);
dialog.setTitle('');
final EditText editTextNama = dialog.findViewById(R.id.edittext_nama);
final EditText editTextNoHp = dialog.findViewById(R.id.edittext_nohp);
final EditText editTextPekerjaan = dialog.findViewById(R.id.edittext_pekerjaan);
final EditText editTextStatus = dialog.findViewById(R.id.edittext_status);
Button buttonSave = dialog.findViewById(R.id.button_save);
buttonSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
User user = new User();
user.setNama(editTextNama.getText().toString());
user.setNoHp(editTextNoHp.getText().toString());
user.setPekerjaan(editTextPekerjaan.getText().toString());
user.setStatus(editTextStatus.getText().toString());
presenter.save(user);
dialog.dismiss();
}
});
Button buttonCancel = dialog.findViewById(R.id.button_cancel);
buttonCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
if (!dialog.isShowing()) {
dialog.show();
}
}
public void showDialogDetail(final User user) {
dialog = new AppCompatDialog(this);
dialog.setContentView(R.layout.dialog_input);
dialog.setTitle('');
final EditText editTextNama = dialog.findViewById(R.id.edittext_nama);
final EditText editTextNoHp = dialog.findViewById(R.id.edittext_nohp);
final EditText editTextPekerjaan = dialog.findViewById(R.id.edittext_pekerjaan);
final EditText editTextStatus = dialog.findViewById(R.id.edittext_status);
editTextNama.setText(user.getNama());
editTextNoHp.setText(user.getNoHp());
editTextPekerjaan.setText(user.getPekerjaan());
editTextStatus.setText(user.getStatus());
Button buttonUpdate = dialog.findViewById(R.id.button_save);
buttonUpdate.setText('Update');
buttonUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
user.setNama(editTextNama.getText().toString());
user.setNoHp(editTextNoHp.getText().toString());
user.setPekerjaan(editTextPekerjaan.getText().toString());
user.setStatus(editTextStatus.getText().toString());
presenter.update(user);
dialog.dismiss();
}
});
Button buttonDelete = dialog.findViewById(R.id.button_cancel);
buttonDelete.setText('Delete');
buttonDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.delete(user);
dialog.dismiss();
}
});
if (!dialog.isShowing()) {
dialog.show();
}
}
Lalu kita buat dan gunakan fungsi-fungsi presenter dan fungsi lainya hingga seperti berikut
public class MainActivity extends AppCompatActivity implements MainView {
private RecyclerView recyclerView;
private Button buttonAdd;
private MainRecyclerAdapter adapter;
private List<User> userList = new ArrayList<>();
private AppCompatDialog dialog;
private MainPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
presenter = new MainPresenterImpl(this);
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MainRecyclerAdapter(userList);
adapter.setOnCallbackListener(new MainRecyclerAdapter.OnCallbackListener() {
@Override
public void onClick(User user) {
showDialogDetail(user);
}
});
recyclerView.setAdapter(adapter);
buttonAdd = findViewById(R.id.button_add);
buttonAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialogInput();
}
});
presenter.load();
}
@Override
public void onLoad(List<User> users) {
userList.clear();
userList.addAll(users);
adapter.notifyDataSetChanged();
}
@Override
public void onSave() {
Toast.makeText(this, 'Berhasil disimpan!', Toast.LENGTH_SHORT).show();
presenter.load();
}
@Override
public void onDelete() {
Toast.makeText(this, 'Berhasil dihapus!', Toast.LENGTH_SHORT).show();
presenter.load();
}
@Override
public void onUpdate() {
Toast.makeText(this, 'Berhasil diperbarui!', Toast.LENGTH_SHORT).show();
presenter.load();
}
public void showDialogInput() {
dialog = new AppCompatDialog(this);
dialog.setContentView(R.layout.dialog_input);
dialog.setTitle('');
final EditText editTextNama = dialog.findViewById(R.id.edittext_nama);
final EditText editTextNoHp = dialog.findViewById(R.id.edittext_nohp);
final EditText editTextPekerjaan = dialog.findViewById(R.id.edittext_pekerjaan);
final EditText editTextStatus = dialog.findViewById(R.id.edittext_status);
Button buttonSave = dialog.findViewById(R.id.button_save);
buttonSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
User user = new User();
user.setNama(editTextNama.getText().toString());
user.setNoHp(editTextNoHp.getText().toString());
user.setPekerjaan(editTextPekerjaan.getText().toString());
user.setStatus(editTextStatus.getText().toString());
presenter.save(user);
dialog.dismiss();
}
});
Button buttonCancel = dialog.findViewById(R.id.button_cancel);
buttonCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
if (!dialog.isShowing()) {
dialog.show();
}
}
public void showDialogDetail(final User user) {
dialog = new AppCompatDialog(this);
dialog.setContentView(R.layout.dialog_input);
dialog.setTitle('');
final EditText editTextNama = dialog.findViewById(R.id.edittext_nama);
final EditText editTextNoHp = dialog.findViewById(R.id.edittext_nohp);
final EditText editTextPekerjaan = dialog.findViewById(R.id.edittext_pekerjaan);
final EditText editTextStatus = dialog.findViewById(R.id.edittext_status);
editTextNama.setText(user.getNama());
editTextNoHp.setText(user.getNoHp());
editTextPekerjaan.setText(user.getPekerjaan());
editTextStatus.setText(user.getStatus());
Button buttonUpdate = dialog.findViewById(R.id.button_save);
buttonUpdate.setText('Update');
buttonUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
user.setNama(editTextNama.getText().toString());
user.setNoHp(editTextNoHp.getText().toString());
user.setPekerjaan(editTextPekerjaan.getText().toString());
user.setStatus(editTextStatus.getText().toString());
presenter.update(user);
dialog.dismiss();
}
});
Button buttonDelete = dialog.findViewById(R.id.button_cancel);
buttonDelete.setText('Delete');
buttonDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.delete(user);
dialog.dismiss();
}
});
if (!dialog.isShowing()) {
dialog.show();
}
}
}
Selesai, lalu coba jalankan hasilnya akan seperti berikut
Kalian juga padat melihat atau download projectnya pada link dibawah ini
https://github.com/lutvie72/android-mvp-sample
Untuk tutorial berikutnya, kita akan membahas penerapan MVP Design Pattern pada API menggunakan retrofit.
0 Komentar