Tugas 10
Nama : Tengku Fredly Reinaldo
NRP : 5025201198
Kelas : Pemrograman Perangkat Bergerak (I)
Tahun Ajaran : Genap 2023/2024
Link Github : Github
Pada tugas 10 ini, kita diminta untuk membuat sebuah aplikasi bernama Dessert Clicker yang mengimplementasikan Activity dan Intent dengan menggunakan Android Studio
Source Code
package com.example.dessertclicker import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent import android.os.Bundle import android.util.Log import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.annotation.DrawableRes import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.calculateEndPadding import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Share import androidx.compose.material3.Scaffold import androidx.compose.material3.Icon import androidx.compose.material3.IconButton 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.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.core.content.ContextCompat import com.example.dessertclicker.data.Datasource import com.example.dessertclicker.model.Dessert import com.example.dessertclicker.ui.theme.DessertClickerTheme private const val TAG = "MainActivity" class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) Log.d(TAG, "onCreate Called") setContent { DessertClickerTheme { Surface( modifier = Modifier .fillMaxSize() .statusBarsPadding(), ) { DessertClickerApp(desserts = Datasource.dessertList) } } } } override fun onStart() { super.onStart() Log.d(TAG, "onStart Called") } override fun onResume() { super.onResume() Log.d(TAG, "onResume Called") } override fun onRestart() { super.onRestart() Log.d(TAG, "onRestart Called") } override fun onPause() { super.onPause() Log.d(TAG, "onPause Called") } override fun onStop() { super.onStop() Log.d(TAG, "onStop Called") } override fun onDestroy() { super.onDestroy() Log.d(TAG, "onDestroy Called") } } fun determineDessertToShow( desserts: List<Dessert>, dessertsSold: Int ): Dessert { var dessertToShow = desserts.first() for (dessert in desserts) { if (dessertsSold >= dessert.startProductionAmount) { dessertToShow = dessert } else { break } } return dessertToShow } private fun shareSoldDessertsInformation(intentContext: Context, dessertsSold: Int, revenue: Int) { val sendIntent = Intent().apply { action = Intent.ACTION_SEND putExtra( Intent.EXTRA_TEXT, intentContext.getString(R.string.share_text, dessertsSold, revenue) ) type = "text/plain" } val shareIntent = Intent.createChooser(sendIntent, null) try { ContextCompat.startActivity(intentContext, shareIntent, null) } catch (e: ActivityNotFoundException) { Toast.makeText( intentContext, intentContext.getString(R.string.sharing_not_available), Toast.LENGTH_LONG ).show() } } @Composable private fun DessertClickerApp( desserts: List<Dessert> ) { 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) } 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) ) } } @Composable private fun DessertClickerAppBar( onShareButtonClicked: () -> Unit, modifier: Modifier = Modifier ) { Row( modifier = modifier, horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, ) { Text( text = stringResource(R.string.app_name), modifier = Modifier.padding(start = dimensionResource(R.dimen.padding_medium)), color = MaterialTheme.colorScheme.onPrimary, style = MaterialTheme.typography.titleLarge, ) IconButton( onClick = onShareButtonClicked, modifier = Modifier.padding(end = dimensionResource(R.dimen.padding_medium)), ) { Icon( imageVector = Icons.Filled.Share, contentDescription = stringResource(R.string.share), tint = MaterialTheme.colorScheme.onPrimary ) } } } @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 = stringResource(R.string.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 = stringResource(R.string.dessert_sold), style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.onSecondaryContainer ) Text( text = dessertsSold.toString(), style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.onSecondaryContainer ) } } @Preview @Composable fun MyDessertClickerAppPreview() { DessertClickerTheme { DessertClickerApp(listOf(Dessert(R.drawable.cupcake, 5, 0))) } }
Screenshoot
Komentar
Posting Komentar