Pada Google I/O 2017 beberapa hari yang lalu, Google memperkenalkan beberapa komponen yang dapat digunakan untuk mempermudah developer dalam membangun aplikasi android. Salah satu komponen tersebut adalah ViewModel
.
Apa itu ViewModel?
ViewModel adalah sebuah kelas yang dirancang untuk menyimpan dan mengelola data yang biasanya berhubungan dengan UI. Sehingga data tersebut dapat digunakan kembali saat terjadi perubahan konfigurasi.
Apa fungsi dari ViewModel?
Terkadang, terjadi beberapa perubahan konfigurasi pada device yang kita gunakan, entah itu saat rotasi layar, munculnya virtual keyboard, dan lain-lain. Saat perubahan itu terjadi, android akan melakukan restart terhadap activity
yang sedang berjalan.
Contoh sederhananya, saat aplikasi kita sedang melakukan request data ke server ketika activity
diakses, ketika data sudah ditampilkan, tiba-tiba user melakukan rotasi layar, maka activity
akan melakukan restart dan melakukan request data dari awal, yang seharusnya tidak perlu dilakukan lagi.
Untuk itulah ViewModel
dibuat, ViewModel
dapat menyimpan dan mengembalikan data yang terikat dengan suatu activity
maupun fragment
sehingga aplikasi kita dapat menggunakan data yang sebelumnya sudah dimiliki.
Menggunakan ViewModel
Catatan: saat artikel ini dibuat, versi komponen saat ini masih berstatus alpha.
Disini saya akan membuat contoh sederhana menggunakan ViewModel
, yaitu aplikasi timer, dimana nantinya timer harus tetap berjalan (tidak mengulang) walaupun terjadi rotasi layar.
Langkah pertama, tentu saja kita membuat sebuah project dengan android studio seperti biasa. Lalu tambahkan dependencies untuk menggunakan komponen ViewModel
.
// build.gradle pada level project
...
allprojects {
repositories {
jcenter()
maven { url 'https://maven.google.com' }
}
}
...
// build.gradle pada level module
...
dependencies {
...
compile "android.arch.lifecycle:runtime:1.0.0-alpha1"
compile "android.arch.lifecycle:extensions:1.0.0-alpha1"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha1"
}
Tambahkan widget Chronometer
pada activity_main.xml
dan jangan lupa definisikan juga pada file MainActivity.java
.
<android.support.constraint.ConstraintLayout 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"
tools:context="id.dekz.viewmodelexample.MainActivity">
<Chronometer
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:id="@+id/chronometer"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp" />
</android.support.constraint.ConstraintLayout>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
...
Chronometer chronometer = (Chronometer) findViewById(R.id.chronometer);
chronometer.start();
}
}
Coba jalankan program diatas, lalu lakukan rotasi layar. Timer akan mengulang dari awal setiap rotasi layar dilakukan karena activity
melakukan restart saat terjadi perubahan konfigurasi.
Untuk menyimpan data dari timer tersebut, buat sebuah kelas ViewModel
, contohnya TimerViewModel.java
.
public class TimerViewModel extends ViewModel {
private Long start;
public Long getStart() {
return start;
}
public void setStart(Long start) {
this.start = start;
}
}
Lakukan perubahan pada MainActivity.java
.
public class MainActivity extends LifecycleActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
...
//init ViewModel
TimerViewModel viewModel = ViewModelProviders.of(this)
.get(TimerViewModel.class);
Chronometer chronometer = (Chronometer) findViewById(R.id.chronometer);
if(viewModel.getStart() == null){
// jika start pada viewmodel belum diset
Long start = SystemClock.elapsedRealtime();
viewModel.setStart(start);
chronometer.setBase(start);
}else{
//jika start menyimpan value, set ke chronometer
Log.d("start",""+viewModel.getStart());
chronometer.setBase(viewModel.getStart());
}
chronometer.start();
}
}
Pada kode diatas, kita mengganti AppCompatActivity
menjadi LifecycleActivity yang nantinya digunakan saat deklarasi TimerViewModel
.
TimerViewModel viewModel = ViewModelProviders.of(this)
.get(TimerViewModel.class);
this
mengarah kepada instance dari LifecycleOwner
karena kita sudah menggunakan LifecycleActivity
. ViewModel
masih dapat bertahan walaupun activity
melakukan restart (onDestroy
lalu onCreate
kembali) saat terjadi perubahan konfigurasi. Gambaran Lifecycle dari ViewModel
dapat dilihat seperti gambar dibawah ini.
Sekarang coba jalankan kembali aplikasinya, dan coba lakukan rotasi layar, maupun beralih sementara ke aplikasi lain lalu kembali ke aplikasi ini. Untuk detail code bisa cek reponya disini.
Referensi
- https://codelabs.developers.google.com/io2017
- https://developer.android.com/topic/libraries/architecture/index.html