MODUL 1
ViewModel dan Status
CAPAIAN PEMBELAJARAN
Mahasiswa dapat menggunakan ViewModel dan Statur dalam aplikasi.
KEBUTUHAN ALAT/BAHAN/SOFTWARE
1. Android Studio Giraffe 2022.3.1 Patch 1 atau yang lebih tinggi
2. Handphone Android Terbaru
3. Kabel data USB.
4. Driver ADB
DASAR TEORI
Arsitektur aplikasi memberikan panduan untuk membantu Anda mengalokasikan tanggung
jawab aplikasi antar-class. Arsitektur aplikasi yang dirancang dengan baik akan membantu
Anda meningkatkan skala aplikasi dan menambahkan fitur lain. Arsitektur juga dapat
menyederhanakan kolaborasi tim.
Prinsip arsitektur yang paling umum adalah pemisahan fokus dan menjalankan UI dari
model.
Memisahkan fokus
Prinsip desain pemisahan fokus menyatakan bahwa aplikasi akan dibagi ke dalam beberapa
class fungsi, masing-masing dengan tanggung jawab yang terpisah.
Menjalankan UI dari model
UI drive dari prinsip model menyatakan bahwa Anda harus menjalankan UI dari suatu
model, terutama model yang persisten. Model adalah komponen yang bertanggung jawab
menangani data untuk sebuah aplikasi. Model tidak terikat dengan elemen UI dan
komponen aplikasi dalam aplikasi Anda, sehingga tidak terpengaruh oleh siklus proses
aplikasi dan masalah terkaitnya.
Arsitektur aplikasi yang direkomendasikan
Dengan mempertimbangkan prinsip arsitektur umum yang disebutkan di bagian
sebelumnya, setiap aplikasi harus memiliki setidaknya dua lapisan:
• Lapisan UI: lapisan yang menampilkan data aplikasi di layar, tetapi terlepas dari
data.
• Lapisan data: lapisan yang menyimpan, mengambil, dan menampilkan data
aplikasi.
Anda dapat menambahkan lapisan lainnya, yang disebut lapisan domain untuk
menyederhanakan dan menggunakan kembali interaksi antara lapisan UI dan data. Lapisan
ini bersifat opsional dan di luar cakupan materi ini.
Catatan: Panah dalam diagram di panduan ini mewakili dependensi di antara class.
Misalnya, lapisan domain bergantung pada class lapisan data.
Lapisan UI
Peran lapisan UI, atau lapisan presentasi, adalah menampilkan data aplikasi di layar. Setiap
kali data berubah karena interaksi pengguna, seperti menekan tombol, UI harus diperbarui
untuk mencerminkan perubahan.
Lapisan UI terdiri dari komponen berikut:
• Elemen UI: komponen yang merender data di layar. Anda membuat elemen ini
menggunakan Jetpack Compose.
• Pemegang status: komponen yang menyimpan data, mengeksposnya ke UI, dan
menangani logika aplikasi. Contoh holder status adalah ViewModel.
ViewModel
Komponen ViewModel menyimpan dan menampilkan status yang digunakan UI. Status UI
adalah data aplikasi yang ditransformasikan oleh ViewModel. ViewModel memungkinkan
aplikasi Anda mengikuti prinsip arsitektur dalam menjalankan UI dari model.
ViewModel menyimpan data terkait aplikasi yang tidak dihancurkan saat aktivitas
dihancurkan dan dibuat ulang oleh framework Android. Tidak seperti instance aktivitas,
objek ViewModel tidak dihancurkan. Aplikasi secara otomatis mempertahankan objek
ViewModel selama perubahan konfigurasi sehingga data yang disimpan segera tersedia
setelah rekomposisi.
Untuk mengimplementasikan ViewModel di aplikasi Anda, perluas class ViewModel, yang
berasal dari library komponen arsitektur, dan menyimpan data aplikasi dalam class
tersebut.
Status UI
UI adalah apa yang dilihat pengguna, dan status UI adalah apa yang menurut aplikasi harus
mereka lihat. UI adalah representasi visual status UI. Setiap perubahan pada status UI akan
segera ditampilkan di UI.
UI adalah hasil dari binding elemen UI di layar dengan status UI.
// Example of UI state definition, do not copy over
data class NewsItemUiState(
val title: String,
val body: String,
val bookmarked: Boolean = false,
...
)
Tidak Berubah
Definisi status UI dalam contoh di atas tidak dapat diubah. Objek yang tidak dapat diubah
memberikan jaminan bahwa beberapa sumber tidak mengubah status aplikasi secara
instan. Perlindungan ini akan mengosongkan UI untuk berfokus pada satu peran: membaca
status dan mengubah elemen UI sebagaimana mestinya. Sehingga, Anda tidak boleh
memodifikasi status UI secara langsung di UI, kecuali jika UI tersebut adalah satu-satunya
sumber datanya. Melanggar prinsip ini menghasilkan beberapa sumber tepercaya untuk
informasi yang sama, sehingga mengakibatkan inkonsistensi data dan bug yang tidak jelas.
PRAKTIK
1. Buat project baru, beri nama ProfilUser.
2. Buka [Link] (Module :app), scroll ke blok dependencies, lalu
tambahkan dependensi berikut untuk ViewModel. Dependensi ini digunakan untuk
menambahkan viewmodel berbasis siklus proses ke aplikasi compose Anda.
dependencies {
// other dependencies
implementation("[Link]:lifecycle-viewmodel-compose:2.6.1")
//...
}
Klik Sync Now
1. Dalam paket [Link] buat paket baru bernama data
2. Dalam paket data, buat class/file Kotlin bernama UserUiState dengan pilihan Data class
package [Link]
data class UserUiState(
val nama : String = "Siti Munawaroh",
val umur : Int = 21
)
3. Dalam paket [Link] buat paket baru bernama model.
4. Dalam paket model buat class/file Kotlin bernama UserViewModel dengan kode
seperti berikut.
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
class UserViewModel : ViewModel() {
private val _userUiState = MutableStateFlow(UserUiState())
val userUiState: StateFlow<UserUiState> = _userUiState.asStateFlow()
fun updateUser(nama: String, umur: Int) {
_userUiState.value = _userUiState.[Link](nama = nama, umur = umur)
}
}
5. Ubah MainActivity menjadi seperti berikut.
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
import [Link]
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
[Link](savedInstanceState)
setContent {
ProfilUserTheme {
// A surface container using the 'background' color from the
theme
Surface(
modifier = [Link](),
color = [Link]
) {
ProfilUserApp()
}
}
}
}
}
@Composable
fun ProfilUserApp(viewModel: UserViewModel = viewModel(),
modifier: Modifier = Modifier,
onUpDateUser: () -> Unit = {[Link]("Anna",25)}
){
val user by [Link]()
Column(
verticalArrangement = [Link],
modifier = [Link]([Link])
) {
Text(
text = "Halo ${[Link]}",
fontSize = [Link],
modifier = [Link](alignment = [Link])
)
Text(
text = "Umur ${[Link]} tahun",
fontSize = [Link],
modifier = [Link](alignment = [Link])
)
Button(
modifier = [Link](alignment =
[Link]),
onClick = onUpDateUser
) {
Text("Update User")
}
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
ProfilUserTheme {
ProfilUserApp()
}
}
Hasil:
Jika button Update User diklik akan menghasilkan:
6. Kita bisa menambahkan OutlinedTextField sehingga user dapat mengisi nama:
7. Tambahkan ke file [Link] :
// jika isian nama diubah akan terjadi rekomposisi (penampilan ulang)
var isianNama by mutableStateOf("")
private set
. . .
fun updateNama(namaUser: String){
isianNama = namaUser
}
8. Kedalam MainActivity, tambahkan kode berikut tepat di atas Button:
OutlinedTextField(
value = [Link], // isian awal TextField
singleLine = true,
shape = [Link],
modifier = [Link](),
colors = [Link](
focusedContainerColor = [Link],
unfocusedContainerColor = [Link],
disabledContainerColor = [Link],
),
onValueChange = { }, // jika user mengetik akan mengerjakan kode ini
label = {
Text(text="Nama")
},
keyboardOptions = [Link](
imeAction = [Link]
),
keyboardActions = KeyboardActions(
onDone = { } // jika tombol <enter> diklik akan menjalankan kode ini
)
)
9. Jalankan aplikasi, coba masukkan nama ke OutlinedTextField. Sampai di sini user masih
belum bisa memasukkan nama. Untuk mengerjakan itu parameter onValueChange
perlu ditambahkan kode untuk mengisinya. Ubahlah kode :
onValueChange = { }, // jika user mengetik akan mengerjakan kode ini
menjadi:
onValueChange = {[Link](it)}, // jika user mengetik akan
mengerjakan kode ini
10. Ubahlah juga di
keyboardActions = KeyboardActions(
onDone = { } // jika tombol <enter> diklik akan menjalankan kode ini
)
Menjadi
keyboardActions = KeyboardActions(
onDone = { onUpDateUser() } // jika tombol <enter> diklik akan menjalankan
kode ini
)
11. Jalankan aplikasi, coba masukkan nama ke OutlinedTextField, seharusnya sudah bisa
memasukkan nama.
Selanjutnya, nama yang sudah diisi oleh user dapat digunakan untuk mengganti nama yang
ditampilkan pada saat button diklik.
12. Tambahkan fungsi berikut di kelas UserViewModel:
fun updateUser2() {
_userUiState.value = _userUiState.[Link](nama = isianNama)
}
13. Dalam MainActivity, fungsi ResponsiApp, ubahlah parameter:
onUpDateUser: () -> Unit = {[Link]("Anna",25)}
menjadi:
onUpDateUser: () -> Unit = {viewModel.updateUser2()}
14. Jalankan aplikasi, ketikkan nama ke OutlinedTextField, kemudian klik button Update
User.
LATIHAN
Tambahkan ke dalam aplikasi untuk mengisi umur, sehingga jika button diklik akan
menampilkan nama dan umur dari masukan user.
TUGAS
Diberikan oleh dosen pengampu
REFERENSI
1. [Link]
state?hl=id&continue=https%3A%2F%[Link]%2Fcourses%2Fpathways%2F
android-basics-compose-unit-4-pathway-1%3Fhl%3Did%23codelab-
https%3A%2F%[Link]%2Fcodelabs%2Fbasic-android-kotlin-compose-
viewmodel-and-state#0