Tugas Week 6 - PPB G - 5025221040
Tugas 6: Membuat Kalkulator Konversi Mata Uang
Nama : Genta Putra PrayogaNRP : 5025221040Kelas : G
Link Github: raymrichigat/ppb-g-tugas6
Tutorial Membuat Aplikasi Konversi Mata uang dengan Jetpack Compose
Dalam era globalisasi dan digital saat ini, kebutuhan untuk mengkonversi mata uang menjadi semakin penting. Baik untuk bisnis internasional, perjalanan luar negeri, atau sekadar memantau nilai investasi, aplikasi konverter mata uang menjadi alat yang sangat berguna. Dalam tutorial ini, kita akan membangun aplikasi konverter mata uang sederhana namun fungsional menggunakan Kotlin dan Jetpack Compose, toolkit UI modern untuk pengembangan Android.
Apa itu Jetpack Compose?
Jetpack Compose adalah toolkit UI modern untuk Android yang memudahkan dan mempercepat pengembangan UI. Compose menggunakan pendekatan deklaratif, yang berarti Anda mendeskripsikan UI aplikasi Anda tanpa perlu mengubah tampilan secara manual melalui hierarki tampilan. Hal ini membuat kode lebih ringkas, intuitif, dan mudah dipelihara.
Fitur Aplikasi Konverter Mata Uang
Aplikasi yang akan kita bangun memiliki fitur-fitur berikut:
- Input jumlah uang yang ingin dikonversi
- Dropdown untuk memilih jenis konversi (IDR ke USD, USD ke IDR, dll.)
- Tombol untuk melakukan konversi
- Tampilan hasil konversi dengan simbol mata uang yang sesuai
Persiapan Proyek
Pertama, buat proyek Android baru dengan template "Empty Compose Activity". Pastikan untuk menyertakan dependensi Jetpack Compose. Setelah proyek terbuat, kita akan mulai dengan file MainActivity.kt.
Implementasi Kode
Berikut adalah kode lengkap untuk aplikasi konverter mata uang kita:
package com.example.currencyconverter
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.CardDefaults
import com.example.currencyconverter.ui.theme.CurrencyConverterTheme
import java.text.NumberFormat
import java.util.Locale
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
CurrencyConverterTheme {
CurrencyConverterApp()
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CurrencyConverterApp() {
var amountToConvert by remember { mutableStateOf("") }
var selectedConversion by remember { mutableStateOf("IDR to USD") }
var result by remember { mutableStateOf("") }
var expanded by remember { mutableStateOf(false) }
val rates = mapOf(
"IDR to USD" to 0.000059,
"USD to IDR" to 16832.0,
"IDR to EUR" to 0.000052,
"EUR to IDR" to 19124.12,
"IDR to JPY" to 0.0085,
"JPY to IDR" to 117.86
)
val currencySymbols = mapOf(
"IDR" to "Rp",
"USD" to "$",
"EUR" to "€",
"JPY" to "¥"
)
val conversionRate = rates[selectedConversion] ?: 1.0
val conversionOptions = rates.keys.toList()
Scaffold(
topBar = {
TopAppBar(title = { Text("Currency Converter") })
},
containerColor = MaterialTheme.colorScheme.background
) { paddingValues ->
Column(
modifier = Modifier
.padding(paddingValues)
.padding(16.dp)
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
shape = RoundedCornerShape(16.dp),
elevation = CardDefaults.cardElevation(6.dp)
) {
Column(modifier = Modifier.padding(16.dp)) {
TextField(
value = amountToConvert,
onValueChange = { amountToConvert = it },
label = { Text("Enter amount") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
// Dropdown menu
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = !expanded }
) {
OutlinedTextField(
value = selectedConversion,
onValueChange = {},
readOnly = true,
label = { Text("Conversion Type") },
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
},
modifier = Modifier
.menuAnchor()
.fillMaxWidth()
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
conversionOptions.forEach { selectionOption ->
DropdownMenuItem(
text = { Text(selectionOption) },
onClick = {
selectedConversion = selectionOption
expanded = false
}
)
}
}
}
Spacer(modifier = Modifier.height(16.dp))
Button(
onClick = {
val amount = amountToConvert.toDoubleOrNull()
if (amount != null) {
val converted = amount * conversionRate
val targetCurrency = selectedConversion.split(" to ").last()
val currencySymbol = currencySymbols[targetCurrency] ?: ""
val formatter = NumberFormat.getNumberInstance(Locale.getDefault())
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
result = "$currencySymbol ${formatter.format(converted)}"
} else {
result = "Invalid input"
}
},
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(12.dp)
) {
Text("Convert", style = MaterialTheme.typography.labelLarge)
}
Spacer(modifier = Modifier.height(24.dp))
if (result.isNotEmpty() && result != "Invalid input") {
Text(
text = "Result: $result",
style = MaterialTheme.typography.titleMedium,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
} else if (result == "Invalid input") {
Text(
text = result,
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.error,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
}
}
}
}
}
}
Penjelasan Komponen Utama
1. State Management
var amountToConvert by remember { mutableStateOf("") }
var selectedConversion by remember { mutableStateOf("IDR to USD") }
var result by remember { mutableStateOf("") }
var expanded by remember { mutableStateOf(false) }
Kita menggunakan remember
dan mutableStateOf
untuk menyimpan dan mengelola state dalam aplikasi Compose. Ketika state berubah, UI akan otomatis diperbarui.
2. Data Kurs Mata Uang
val rates = mapOf(
"IDR to USD" to 0.000059,
"USD to IDR" to 16832.0,
"IDR to EUR" to 0.000052,
"EUR to IDR" to 19124.12,
"IDR to JPY" to 0.0085,
"JPY to IDR" to 117.86
)
val currencySymbols = mapOf(
"IDR" to "Rp",
"USD" to "$",
"EUR" to "€",
"JPY" to "¥"
)
Untuk aplikasi sederhana ini, kita mendefinisikan kurs mata uang dan simbol secara hardcoded. Dalam aplikasi produksi, Anda mungkin ingin menggunakan API untuk mendapatkan kurs mata uang terbaru.
3. UI Components
TextField untuk Input
TextField(
value = amountToConvert,
onValueChange = { amountToConvert = it },
label = { Text("Enter amount") },
modifier = Modifier.fillMaxWidth()
)
TextField memungkinkan pengguna memasukkan jumlah yang ingin dikonversi.
Dropdown untuk Pilihan Konversi
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = !expanded }
) {
OutlinedTextField(
value = selectedConversion,
onValueChange = {},
readOnly = true,
label = { Text("Conversion Type") },
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
},
modifier = Modifier
.menuAnchor()
.fillMaxWidth()
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
conversionOptions.forEach { selectionOption ->
DropdownMenuItem(
text = { Text(selectionOption) },
onClick = {
selectedConversion = selectionOption
expanded = false
}
)
}
}
}
ExposedDropdownMenuBox memberikan antarmuka dropdown yang elegan untuk memilih jenis konversi mata uang.
Button untuk Konversi
Button(
onClick = {
val amount = amountToConvert.toDoubleOrNull()
if (amount != null) {
val converted = amount * conversionRate
val targetCurrency = selectedConversion.split(" to ").last()
val currencySymbol = currencySymbols[targetCurrency] ?: ""
val formatter = NumberFormat.getNumberInstance(Locale.getDefault())
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
result = "$currencySymbol ${formatter.format(converted)}"
} else {
result = "Invalid input"
}
},
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(12.dp)
) {
Text("Convert", style = MaterialTheme.typography.labelLarge)
}
Button dengan fungsi onClick yang melakukan konversi mata uang berdasarkan input pengguna dan pilihan konversi.
Menampilkan Hasil
if (result.isNotEmpty() && result != "Invalid input") {
Text(
text = "Result: $result",
style = MaterialTheme.typography.titleMedium,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
} else if (result == "Invalid input") {
Text(
text = result,
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.error,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
}
Menampilkan hasil konversi atau pesan error jika input tidak valid.
Kesimpulan
Dengan Jetpack Compose, kita dapat membuat aplikasi konverter mata uang yang elegan dan fungsional dengan kode yang relatif sederhana. Pendekatan deklaratif Compose memudahkan kita untuk fokus pada bagaimana UI harus terlihat, bukan bagaimana mengubahnya secara imperatif.
Aplikasi ini dapat dikembangkan lebih lanjut dengan menambahkan fitur seperti:
- Mengambil kurs mata uang terbaru dari API
- Menambahkan lebih banyak jenis mata uang
- Menyimpan riwayat konversi
- Menambahkan fitur grafik untuk melihat perubahan kurs mata uang dari waktu ke waktu
Komentar
Posting Komentar