diff --git a/app/src/main/java/com/example/tiptime/MainActivity.kt b/app/src/main/java/com/example/tiptime/MainActivity.kt index e05f23a..799ad15 100644 --- a/app/src/main/java/com/example/tiptime/MainActivity.kt +++ b/app/src/main/java/com/example/tiptime/MainActivity.kt @@ -6,6 +6,7 @@ import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.annotation.DrawableRes import androidx.annotation.StringRes +import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardOptions @@ -20,11 +21,9 @@ import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.compose.ui.graphics.Brush import com.example.tiptime.ui.theme.TipTimeTheme import kotlin.math.pow -import kotlin.math.roundToInt -import androidx.compose.foundation.background -import androidx.compose.ui.graphics.Brush class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -44,15 +43,21 @@ class MainActivity : ComponentActivity() { fun BmiCalculatorLayout() { var heightInput by remember { mutableStateOf("") } var weightInput by remember { mutableStateOf("") } + var useMetricSystem by remember { mutableStateOf(true) } // ✅ toggle sistem satuan var errorMessage by remember { mutableStateOf("") } - - // State untuk hasil BMI - var bmiResult by remember { mutableStateOf(null) } - var bmiCategory by remember { mutableStateOf("") } + var showResult by remember { mutableStateOf(false) } // ✅ hasil hanya tampil setelah tombol ditekan val height = heightInput.toFloatOrNull() ?: 0f val weight = weightInput.toFloatOrNull() ?: 0f - val isValid = validateInput(height, weight) + + val isValid = validateInput(height, weight, useMetricSystem) + + // Konversi tinggi & berat ke sistem metrik (meter & kg) + val heightInMeters = if (useMetricSystem) height / 100f else height * 0.0254f + val weightInKg = if (useMetricSystem) weight else weight * 0.453592f + + val bmi = if (isValid && showResult) weightInKg / heightInMeters.pow(2) else 0f + val category = if (isValid && showResult) getBMICategory(bmi) else "" Box( modifier = Modifier @@ -70,6 +75,7 @@ fun BmiCalculatorLayout() { ) { Column(horizontalAlignment = Alignment.CenterHorizontally) { + // Judul Aplikasi Row(verticalAlignment = Alignment.CenterVertically) { Icon( painter = painterResource(id = R.drawable.ic_launcher_foreground), @@ -88,6 +94,22 @@ fun BmiCalculatorLayout() { Spacer(modifier = Modifier.height(24.dp)) + // Toggle Sistem Satuan + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center + ) { + Text("SI (kg, cm)") + Switch( + checked = !useMetricSystem, + onCheckedChange = { useMetricSystem = !useMetricSystem } + ) + Text("USC (lbs, inci)") + } + + Spacer(modifier = Modifier.height(24.dp)) + + // Card Input Card( elevation = CardDefaults.cardElevation(defaultElevation = 8.dp), colors = CardDefaults.cardColors( @@ -100,7 +122,7 @@ fun BmiCalculatorLayout() { horizontalAlignment = Alignment.CenterHorizontally ) { EditNumberField( - label = R.string.height, + label = if (useMetricSystem) R.string.height else R.string.height_inch, leadingIcon = R.drawable.number, keyboardOptions = KeyboardOptions( keyboardType = KeyboardType.Number, @@ -114,7 +136,7 @@ fun BmiCalculatorLayout() { ) EditNumberField( - label = R.string.weight, + label = if (useMetricSystem) R.string.weight else R.string.weight_lbs, leadingIcon = R.drawable.number, keyboardOptions = KeyboardOptions( keyboardType = KeyboardType.Number, @@ -129,15 +151,18 @@ fun BmiCalculatorLayout() { Spacer(modifier = Modifier.height(24.dp)) + // Tombol Hitung BMI Button( onClick = { if (!isValid) { - errorMessage = "Masukkan tinggi (20–250 cm) dan berat (10–250 kg) yang valid!" - bmiResult = null + showResult = false + errorMessage = if (useMetricSystem) + "Masukkan tinggi (20–250 cm) dan berat (10–250 kg) yang valid!" + else + "Masukkan tinggi (≥4 inci) dan berat (5–550 lbs) yang valid!" } else { errorMessage = "" - bmiResult = calculateBMI(weight, height) - bmiCategory = getBMICategory(bmiResult!!) + showResult = true } }, modifier = Modifier @@ -145,9 +170,13 @@ fun BmiCalculatorLayout() { .height(56.dp), elevation = ButtonDefaults.elevatedButtonElevation(8.dp) ) { - Text(text = "Hitung BMI", style = MaterialTheme.typography.titleMedium) + Text( + text = "Hitung BMI", + style = MaterialTheme.typography.titleMedium + ) } + // Pesan error if (errorMessage.isNotEmpty()) { Text( text = errorMessage, @@ -157,9 +186,9 @@ fun BmiCalculatorLayout() { ) } - // Tampilkan hasil hanya jika sudah ditekan - bmiResult?.let { bmi -> - val categoryColor = when (bmiCategory) { + // Hasil BMI hanya tampil setelah ditekan tombol + if (showResult && isValid) { + val categoryColor = when (category) { "Kurus" -> MaterialTheme.colorScheme.tertiaryContainer "Normal" -> MaterialTheme.colorScheme.primaryContainer "Kelebihan Berat" -> MaterialTheme.colorScheme.secondaryContainer @@ -182,7 +211,7 @@ fun BmiCalculatorLayout() { style = MaterialTheme.typography.titleLarge ) Text( - text = "Kategori: $bmiCategory", + text = "Kategori: $category", style = MaterialTheme.typography.bodyLarge ) } @@ -192,11 +221,6 @@ fun BmiCalculatorLayout() { } } - - -/** - * Fungsi untuk membuat TextField input angka - */ @Composable fun EditNumberField( @StringRes label: Int, @@ -217,18 +241,6 @@ fun EditNumberField( ) } -/** - * Menghitung nilai BMI berdasarkan berat (kg) dan tinggi (cm) - * Rumus: BMI = berat / (tinggi/100)^2 - */ -fun calculateBMI(weight: Float, height: Float): Float { - if (height <= 0) return 0f - return weight / (height / 100).pow(2) -} - -/** - * Menentukan kategori BMI - */ fun getBMICategory(bmi: Float): String { return when { bmi < 18.5 -> "Kurus" @@ -238,11 +250,11 @@ fun getBMICategory(bmi: Float): String { } } -/** - * Validasi input agar nilai masuk akal - */ -fun validateInput(height: Float, weight: Float): Boolean { - return height in 20f..250f && weight in 10f..250f +fun validateInput(height: Float, weight: Float, useMetric: Boolean): Boolean { + return if (useMetric) + height in 20f..250f && weight in 10f..250f + else + height >= 4f && height <= 100f && weight in 5f..550f } @Preview(showBackground = true) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 04e6db2..7bdf471 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -22,4 +22,6 @@ Gunakan Unit USC (lbs/in)? BMI Anda: %s Kategori: %s + Tinggi Badan + Berat Badan