Membuat Aplikasi Dice Roller Interaktif dengan menggunakan Komponen Button

 Pendahuluan

Pada pertemuan keempat kuliah Pemrograman Perangkat Bergerak kemarin kita telah mempelajari tentang Komponen Button. Latihan pada pertemuan kali ini kita akan membuat sebuah aplikasi Dice Roller Interaktif. Aplikasi tersebut nanti memungkinkan pengguna melempar dadu dengan mengetuk composable Button. Hasil lemparan nantinya akan ditampilkan dengan composable Image pada layar.

Membuat Aplikasi Dice Roller Interaktif

    Kali ini, kita akan memulai proyek baru dengan menggunakan templat yang telah tersedia di Android Studio. Seperti sebelumnya, kita akan memilih templat Empty Activity. Proyek ini bertujuan untuk membuat aplikasi sederhana bernama Dice Roller App. Aplikasi ini akan mensimulasikan lemparan dadu dan menampilkan hasilnya.
  • Membuka Android Studi dan memilih opsi "Empty Activity".
  • Setelah memilih template Empty Activity kita akan menuliskan nama proyek kita yaitu "Dice Roller" dan memilih level API minimum untuk proyek kita, disini kita akan memilih API 24 (Nougat).
  • Setelah kode template berhasil dimuat kita akan mengubah struktur kode default proyek.
Kita akan mengubah beberapa struktur kode dari project awal menyesuaikan dengan kebutuhan dari aplikasi Dice Roller ini. 
📙 Kita akan menyusun kode default seperti ini:
     - Menghapus dungsi DefaultPreview() 
    - Membuat Fungsi DiceWithButtonAndImage() dengan anotasi @Composable
📙 Fungsi Composable ini nantinya mewakili komponen UI dari tata letak dan logika klik button serta tampilan gambar dice (dadu).
  - Menghapus fungsi Greeting(name:string).
  - Membuat fungsi DiceRollerApp() dengan anotasi @Composable dan @Preview.
📙 Kemudian kita akan memanggil fungsi DiceRollerApp() pada DiceRollerTheme di class MainActivity.
    - Menghapus Greeting("Android") dan menggantinya dengan DiceRollerApp().
  • Kemudian kita akan membuat infrastruktur tata letak. 
Untuk membuat tata letak pada komponen UI dari komponen aplikasi ini, kita perlu menambahkan argumen modifier dari jenis Modifier dan menetapkan nilai default Modifier pada fungsi DiceWithButtonAndImage.

Lalu kita akan membuat rantai metode fillMaxSize() ke objek Modifier sehingga tata letak mengisi seluruh layar. Kemudian buat juga rantai metode wrapContentSize() ke objek Modifier yang meneruskan argumen Alignment.Center untuk memusatkan komponen.  

  • Membuat tata letak vertikal

Pada Compose, tata letak vertikal dibuat menggunakan fungsi Column(). Fungsi tersebut ada fungsi tata letak composable yang menempatkan turunannya dalam urutan secara vertikal.

Untuk membuat tata letak vertikal kita akan melakukan langkah seperti ini:

📙 Menambahkan fungsi Column() dalam fungsi DiceWithButtonAndImage().

📙 Meneruskan argumen modifier dari metode DiceWithButtonAndImage() ke argumen pengubah Column
Argumen  modifier disini memastikan bahwa Composable dalam fungsi Column() mematuhi batasan yang dipanggil pada instance modifier.

📙 Meneruskan argumen horizontalAlignment ke fungsi Column(), kemudian menetapkan nilai Alignment.CenterHorizontally

  • Menambahkan komponen Button dan String "Roll".
Pada file string.xml kita akan menambahkan string dan menetapkan nilainya ke nilai Roll
Selanjutnya kita akan menambahkan fungsi Button() di dalam lambda Column(). Di dalam lambda Button, kita akan mengisinya dengan fungsi Text(). Kemudian kita akan melanjutkan ID resource string dari string roll ke fungsi stringResource() dan teruskan hasilnya ke composable Text().

  • Menambahkan gambar dadu
Pertama, kita akan import gambar dadu yang sudah disediakan dari codelab. Berikut adalah langkahnya:
- Pada Android Studio, klik View -> Tool Windows -> Resource Manager.
- Klik (+) -> Import Drawables untuk membuka file browser.
- Kemudian cari file gambar dadu, lalu pilih semua file dan klik lanjutkan untuk menguploadnya.

Kemudian untu menambahkan gambar pada project ini, kita akan menggunakan fungsi Image() dan menempatkannya sebelum fungsi Button(). Lalu kita akan teruskan argumen painter ke fungsi Image(), lalu tetapkan nilai painterResource yang menerima argumen ID resource drawable. Selain itu kita akan menambahkan fungsi Spacer() untuk memberikan jarak antara gambar dengan tombol. 

  • Membuat logika pelemparan dadu
Kita akan membuat tombol menjadi interaktif dengan cara sebagai berikut. 
-Pada fungsi DiceWithButtonAndImage() sebelum fungsi Column(), buatlah variabel result dan tetapkan agar sama dengan nilai 1. 
-Isi lambda parameter onClick dengan fungsi random pada rentang angka 1 - 6 (dipisahkan dengan ..)

Pada bagian sebelumnya, kita telah membuat variabel result dan melakukan hard code pada nilai 1. Pada akhirnya, nilai variabel result akan direset saat tombol Roll diketuk dan akan menentukan gambar yang ditampilkan. 

Composable bersifat stateless secara default, yang berarti bahwa composable tersebut tidak memiliki nilai dan dapat disusun ulang oleh sistem kapan saja sehingga mengakibatkan nilai tersebut direset. Namun, Compose menyediakan cara yang praktis untuk menghindari hal ini. Fungsi composable dapat menyimpan objek dalam memori menggunakan composable remember.

Fungsi mutableStateOf() akan menampilkan objek yang dapat diamati. Pada dasarnya ini berarti bahwa saat nilai variabel result berubah, rekomposisi akan dipicu, nilai hasilnya akan tercermin, dan UI akan di muat ulang.

Sekarang, saat tombol diketuk, variabel result akan diupdate dengan nilai angka acak. Variabel result dapat digunakan untuk menentukan gambar yang akan ditampilkan.

Di bawah pembuatan instance variabel result, buat variabel imageResource tetap yang ditetapkan ke ekspresi when yang menerima variabel result, lalu tetapkan setiap kemungkinan hasil ke drawable-nya.

Hasil Akhir Project :



Kode Sumber dari proyek Dice Roller App
File MainActivity:
package com.example.diceroller
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.diceroller.ui.theme.DiceRollerTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DiceRollerTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
DiceRollerApp()
}
}
}
}
}
@Preview
@Composable
fun DiceRollerApp() {
DiceWithButtonAndImage()
}
@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier
.fillMaxSize()
.wrapContentSize(Alignment.Center)) {
var result by remember {
mutableStateOf(1)
}
val imageResource = when (result) {
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
else -> R.drawable.dice_6
}
Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) {
Image(painter = painterResource(imageResource), contentDescription = result.toString() )
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { result = (1..6).random() }) {
Text(stringResource(R.string.roll))
}
}
}
File Strings.xml:
<resources>
<string name="app_name">Dice Roller</string>
<string name="roll">Roll</string>
</resources>
Selengkapnya kode sumber dapat diakses di Github

Referensi

Comments