Nama: Richard Ryan
NRP: 5025211141
Kelas: PPB (G)
Tema: Dessert Clicker
Link Github : Github
Penjelasan Kode
Pertama buat data class dan daftar objek yang akan digunakan
data class Dessert (
val imageId: Int,
val price: Int,
val startProductionAmount: Int
)
val dessertList = listOf(
Dessert(R.drawable.cupcake, 5, 0),
Dessert(R.drawable.donut, 10, 5),
Dessert(R.drawable.eclair, 15, 20),
Dessert(R.drawable.froyo, 30, 50),
Dessert(R.drawable.gingerbread, 50, 100),
Dessert(R.drawable.honeycomb, 100, 200),
Dessert(R.drawable.icecreamsandwich, 500, 500),
Dessert(R.drawable.jellybean, 1000, 1000),
Dessert(R.drawable.kitkat, 2000, 2000),
Dessert(R.drawable.lollipop, 3000, 4000),
Dessert(R.drawable.marshmallow, 4000, 8000),
Dessert(R.drawable.nougat, 5000, 16000),
Dessert(R.drawable.oreo, 6000, 20000)
)Setelah itu buat beberapa variabel yang akan digunakan untuk menyimpan beberapa data
- revenue digunakan untuk menyimpan total pendapatan
- dessertsSold digunakan untuk menyimpan jumlah dessert terjual, angka ini juga menentukan dessert apakah yang akan muncul
- currentDessertIndex digunakan untuk menyimpan index dessert yang ditampilkan saat ini, dengan variabel currentDessertPrice dan currentDessertImageId menyimpan harga dan id gambar dessert saat ini
var revenue by rememberSaveable { mutableStateOf(0) }
var dessertsSold by rememberSaveable { mutableStateOf(0) }
val currentDessertIndex by rememberSaveable { mutableStateOf(0) }
var currentDessertPrice by rememberSaveable {
mutableStateOf(desserts[currentDessertIndex].price)
}
var currentDessertImageId by rememberSaveable {
mutableStateOf(desserts[currentDessertIndex].imageId)
}
Setelah itu, semua UI akan diwrap dengan Scaffold() agar bisa dibuat TopBar dengan mudah
Top bar terdiri dari sebuah text "Dessert Clicker" di sisi kiri dan tombol share di kanan yang jika diklik akan memunculkan sendIntent berisikan detail jumlah dessert yang diklik & penghasilannya
Kemudian, isi dari halaman UInya sendiri akan menggunakan komponen DessertClickerScreen()
private fun shareSoldDessertsInformation(intentContext: Context, dessertsSold: Int, revenue: Int) {
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(
Intent.EXTRA_TEXT,
"I've clicked $dessertsSold Desserts for a total of $revenue #AndroidDessertClicker"
)
type = "text/plain"
}
val shareIntent = Intent.createChooser(sendIntent, null)
try {
ContextCompat.startActivity(intentContext, shareIntent, null)
} catch (e: ActivityNotFoundException) {
Toast.makeText(
intentContext,
"Sharing Not Available",
Toast.LENGTH_LONG
).show()
}
}
@Composable
private fun DessertClickerAppBar(
onShareButtonClicked: () -> Unit,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier,
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = "Dessert Clicker",
modifier = Modifier.padding(start = 16.dp),
color = MaterialTheme.colorScheme.onPrimary,
style = MaterialTheme.typography.titleLarge,
)
IconButton(
onClick = onShareButtonClicked,
modifier = Modifier.padding(end = 16.dp),
) {
Icon(
imageVector = Icons.Filled.Share,
contentDescription = "Share",
tint = MaterialTheme.colorScheme.onPrimary
)
}
}
}
@Composable
private fun DessertClickerApp(desserts: List<Dessert>) {
Scaffold(
topBar = {
val intentContext = LocalContext.current
val layoutDirection = LocalLayoutDirection.current
DessertClickerAppBar(
onShareButtonClicked = {
shareSoldDessertsInformation(
intentContext = intentContext,
dessertsSold = dessertsSold,
revenue = revenue
)
},
modifier = Modifier
.fillMaxWidth()
.padding(
start = WindowInsets.safeDrawing.asPaddingValues()
.calculateStartPadding(layoutDirection),
end = WindowInsets.safeDrawing.asPaddingValues()
.calculateEndPadding(layoutDirection),
)
.background(MaterialTheme.colorScheme.primary)
)
}
) { contentPadding ->
DessertClickerScreen(
revenue = revenue,
dessertsSold = dessertsSold,
dessertImageId = currentDessertImageId,
onDessertClicked = {
revenue += currentDessertPrice
dessertsSold++
val dessertToShow = determineDessertToShow(desserts, dessertsSold)
currentDessertImageId = dessertToShow.imageId
currentDessertPrice = dessertToShow.price
},
modifier = Modifier.padding(contentPadding)
)
}Bagian ini menjadi detail isi halaman
- Pertama, akan ditambahkan image untuk background, kemudian di tambahkan secara terpisah gambar dessert yang akan dijual. Lalu ditambahkan pula di bagian bawah layar detail transaksi yang berisikan jumlah dessert terjual dan penghasilan total dengan komponen TransactionInfo()
- Apabila diperhatikan dari komponen App sebelumnya, ketika gambar dessert diklik, maka akan secara otomatis menambah penghasilan dan jumlah terjual. Setelah itu akan dilakukan pengecekan apakah dessert perlu diubah dengan dipanggil fungsi determineDessertToShow()
- Komponen TransactionInfo() sendiri terdiri dari DessertsSoldInfo() yang digunakan untuk menampilkan jumlah dessert terjual dan RevenueInfo yang menampilkan total penghasilan
- Pada kedua komponen tersebut, digunakan Arrangement.SpaceBetween sehingga mereka akan ada di sisi paling kiri dan kanan layar
@Composable
fun DessertClickerScreen(
revenue: Int,
dessertsSold: Int,
@DrawableRes dessertImageId: Int,
onDessertClicked: () -> Unit,
modifier: Modifier = Modifier
) {
Box(modifier = modifier) {
Image(
painter = painterResource(R.drawable.bakery_back),
contentDescription = null,
contentScale = ContentScale.Crop
)
Column {
Box(
modifier = Modifier
.weight(1f)
.fillMaxWidth(),
) {
Image(
painter = painterResource(dessertImageId),
contentDescription = null,
modifier = Modifier
.width(dimensionResource(R.dimen.image_size))
.height(dimensionResource(R.dimen.image_size))
.align(Alignment.Center)
.clickable { onDessertClicked() },
contentScale = ContentScale.Crop,
)
}
TransactionInfo(
revenue = revenue,
dessertsSold = dessertsSold,
modifier = Modifier.background(MaterialTheme.colorScheme.secondaryContainer)
)
}
}
}
@Composable
private fun TransactionInfo(
revenue: Int,
dessertsSold: Int,
modifier: Modifier = Modifier
) {
Column(modifier = modifier) {
DessertsSoldInfo(
dessertsSold = dessertsSold,
modifier = Modifier
.fillMaxWidth()
.padding(dimensionResource(R.dimen.padding_medium))
)
RevenueInfo(
revenue = revenue,
modifier = Modifier
.fillMaxWidth()
.padding(dimensionResource(R.dimen.padding_medium))
)
}
}
@Composable
private fun RevenueInfo(revenue: Int, modifier: Modifier = Modifier) {
Row(
modifier = modifier,
horizontalArrangement = Arrangement.SpaceBetween,
) {
Text(
text = "Total Revenue",
style = MaterialTheme.typography.headlineMedium,
color = MaterialTheme.colorScheme.onSecondaryContainer
)
Text(
text = "$${revenue}",
textAlign = TextAlign.Right,
style = MaterialTheme.typography.headlineMedium,
color = MaterialTheme.colorScheme.onSecondaryContainer
)
}
}
@Composable
private fun DessertsSoldInfo(dessertsSold: Int, modifier: Modifier = Modifier) {
Row(
modifier = modifier,
horizontalArrangement = Arrangement.SpaceBetween,
) {
Text(
text = "Desserts sold",
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onSecondaryContainer
)
Text(
text = dessertsSold.toString(),
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onSecondaryContainer
)
}
}



Comments
Post a Comment