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