Furstin Aprilavia Putri - 5025221234 - PPB D
Membuat Aplikasi Aplikasi Konversi Mata Uang 💱
1. Pendahuluan
Pada Tugas ke-6 ini, saya membuat aplikasi konversi mata uang sederhana menggunakan Jetpack Compose. Aplikasi ini mendukung tiga mata uang — IDR (🇮🇩), USD (🇺🇸), dan EUR (🇪🇺).
2. Aplikasi
Kode lengkap dapat dilihat di GitHub : https://github.com/furstinvia/ppb-d-6-currencyconverter.git
1. Data Kurs Tukar
Data kurs disimpan dalam exchangeRates, berbentuk Map<String, Map<String, Double>>, untuk memudahkan pencarian nilai tukar dari dan ke mata uang yang berbeda:
private val exchangeRates = mapOf( "IDR" to mapOf("USD" to 0.00005955, "EUR" to 0.00005243), "USD" to mapOf("IDR" to 16924.49, "EUR" to 0.89), "EUR" to mapOf("IDR" to 19072.87, "USD" to 1.12) )
2. UI Form Konversi
Pengguna memasukkan jumlah uang melalui OutlinedTextField dengan KeyboardType.Number. Ada dua dropdown (asal dan tujuan mata uang), yang ditampilkan menggunakan emoji bendera:
val currencies = listOf("🇮🇩 IDR", "🇺🇸 USD", "🇪🇺 EUR")
CurrencyDropdown("Dari", currencies, fromCurrency) { fromCurrency = it } CurrencyDropdown("Ke", currencies, toCurrency) { toCurrency = it }
3. Proses Konversi
Setelah menekan tombol Konversi, nilai akan dikonversi berdasarkan kurs dan hasil ditampilkan:
val from = fromCurrency.takeLast(3) // Mengambil kode mata uang dari emoji val to = toCurrency.takeLast(3) val rate = exchangeRates[from]?.get(to) val converted = amount * rate result = "%.2f $to".format(converted)
4. Dropdown Mata Uang
Dropdown menggunakan ExposedDropdownMenuBox dari Material3, dan menampilkan emoji dengan kode mata uang:
@Composable fun CurrencyDropdown(...) { ... ExposedDropdownMenu { options.forEach { option -> DropdownMenuItem( text = { Text(option) }, // 👈 menampilkan 🇮🇩 IDR misalnya onClick = { onOptionSelected(option) expanded = false } ) } } }
5. Tampilan Akhir
Semua elemen diletakkan secara vertikal dengan padding dan spasi yang cukup agar tampilan nyaman di mata:
Column(
modifier = Modifier
.fillMaxSize()
.padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
)
atau klik disini
Kode Lengkap
package com.example.currencyconverter import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp class MainActivity : ComponentActivity() { private val exchangeRates = mapOf( "IDR" to mapOf("USD" to 0.00005955, "EUR" to 0.00005243), "USD" to mapOf("IDR" to 16924.49, "EUR" to 0.89), "EUR" to mapOf("IDR" to 19072.87, "USD" to 1.12) ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MaterialTheme( colorScheme = lightColorScheme( primary = Color(0xFFFFC1CC), // Soft pastel pink onPrimary = Color.White, background = Color(0xFFFFF1F3), surface = Color.White, onSurface = Color(0xFF333333) ) ) { CurrencyConverterApp() } } } @Composable fun CurrencyConverterApp() { val currencies = listOf("🇮🇩 IDR", "🇺🇸 USD", "🇪🇺 EUR") var amountInput by remember { mutableStateOf("") } var fromCurrency by remember { mutableStateOf("🇮🇩 IDR") } var toCurrency by remember { mutableStateOf("🇺🇸 USD") } var result by remember { mutableStateOf("") } Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { Column( modifier = Modifier .fillMaxSize() .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Text( "💱 Kalkulator Konversi Mata Uang", fontSize = 22.sp, style = TextStyle(fontFamily = FontFamily.SansSerif) ) Spacer(modifier = Modifier.height(16.dp)) OutlinedTextField( value = amountInput, onValueChange = { amountInput = it }, label = { Text("Jumlah Uang", fontFamily = FontFamily.SansSerif) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), modifier = Modifier.fillMaxWidth(), textStyle = TextStyle(fontFamily = FontFamily.SansSerif) ) Spacer(modifier = Modifier.height(12.dp)) Row( horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically ) { CurrencyDropdown("Dari", currencies, fromCurrency) { fromCurrency = it } CurrencyDropdown("Ke", currencies, toCurrency) { toCurrency = it } } Spacer(modifier = Modifier.height(20.dp)) Button( onClick = { val amount = amountInput.toDoubleOrNull() if (amount == null) { result = "Masukkan jumlah yang valid" return@Button } val from = fromCurrency.takeLast(3) val to = toCurrency.takeLast(3) if (from == to) { result = "%.2f $to".format(amount) } else { val rate = exchangeRates[from]?.get(to) result = if (rate != null) { val converted = amount * rate "%.2f $to".format(converted) } else { "Kurs tidak tersedia" } } }, modifier = Modifier.fillMaxWidth(), colors = ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.primary, contentColor = Color.White ) ) { Text("Konversi", fontFamily = FontFamily.SansSerif) } Spacer(modifier = Modifier.height(16.dp)) Text( text = "Hasil: $result", fontSize = 18.sp, fontFamily = FontFamily.SansSerif ) } } } @OptIn(ExperimentalMaterial3Api::class) @Composable fun CurrencyDropdown( label: String, options: List<String>, selectedOption: String, onOptionSelected: (String) -> Unit ) { var expanded by remember { mutableStateOf(false) } ExposedDropdownMenuBox( expanded = expanded, onExpandedChange = { expanded = !expanded } ) { OutlinedTextField( value = selectedOption, onValueChange = {}, readOnly = true, label = { Text(label, fontFamily = FontFamily.SansSerif) }, modifier = Modifier.menuAnchor(), textStyle = TextStyle(fontFamily = FontFamily.SansSerif) ) ExposedDropdownMenu( expanded = expanded, onDismissRequest = { expanded = false } ) { options.forEach { option -> DropdownMenuItem( text = { Text(option, fontFamily = FontFamily.SansSerif) }, onClick = { onOptionSelected(option) expanded = false } ) } } } } }
Comments
Post a Comment