ppp
This commit is contained in:
commit
f4cbea5b6c
209
app/src/main/java/com/example/kalkulatorbmi/MainScreen.kt
Normal file
209
app/src/main/java/com/example/kalkulatorbmi/MainScreen.kt
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
package com.example.kalkulatorbmi
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.animation.fadeIn
|
||||||
|
import androidx.compose.animation.slideInVertically
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.*
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import kotlin.math.pow
|
||||||
|
|
||||||
|
// Enum untuk merepresentasikan sistem unit yang dipilih
|
||||||
|
enum class UnitSystem {
|
||||||
|
Metric, USC
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MainScreen(navController: NavController) {
|
||||||
|
// --- STATE UNTUK SEMUA FITUR ---
|
||||||
|
var unitSystem by remember { mutableStateOf(UnitSystem.Metric) }
|
||||||
|
var umur by remember { mutableStateOf("") }
|
||||||
|
var jenisKelamin by remember { mutableStateOf<String?>(null) }
|
||||||
|
|
||||||
|
// State untuk Metric
|
||||||
|
var tinggiCm by remember { mutableStateOf("") }
|
||||||
|
var beratKg by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
// State untuk USC
|
||||||
|
var tinggiFt by remember { mutableStateOf("") }
|
||||||
|
var tinggiIn by remember { mutableStateOf("") }
|
||||||
|
var beratLbs by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
var bmiResult by remember { mutableStateOf<Float?>(null) }
|
||||||
|
var bmiCategory by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
// Variabel Warna dari Tema
|
||||||
|
val surfaceVariantColor = MaterialTheme.colorScheme.surfaceVariant
|
||||||
|
val errorColor = MaterialTheme.colorScheme.error
|
||||||
|
val errorContainerColor = MaterialTheme.colorScheme.errorContainer
|
||||||
|
val primaryColor = MaterialTheme.colorScheme.primary
|
||||||
|
val backgroundColor = MaterialTheme.colorScheme.background
|
||||||
|
val onBackgroundColor = MaterialTheme.colorScheme.onBackground
|
||||||
|
val secondaryColor = MaterialTheme.colorScheme.secondary
|
||||||
|
|
||||||
|
var bmiColor by remember { mutableStateOf(surfaceVariantColor) }
|
||||||
|
val focusManager = LocalFocusManager.current
|
||||||
|
|
||||||
|
fun calculateBmi() {
|
||||||
|
focusManager.clearFocus()
|
||||||
|
var bmi: Float? = null
|
||||||
|
|
||||||
|
if (unitSystem == UnitSystem.Metric) {
|
||||||
|
val tinggiCmFloat = tinggiCm.toFloatOrNull()
|
||||||
|
val beratKgFloat = beratKg.toFloatOrNull()
|
||||||
|
if (tinggiCmFloat != null && beratKgFloat != null && tinggiCmFloat > 0) {
|
||||||
|
val tinggiM = tinggiCmFloat / 100
|
||||||
|
bmi = beratKgFloat / tinggiM.pow(2)
|
||||||
|
}
|
||||||
|
} else { // USC
|
||||||
|
val tinggiFtFloat = tinggiFt.toFloatOrNull() ?: 0f
|
||||||
|
val tinggiInFloat = tinggiIn.toFloatOrNull() ?: 0f
|
||||||
|
val beratLbsFloat = beratLbs.toFloatOrNull()
|
||||||
|
if (beratLbsFloat != null && (tinggiFtFloat > 0 || tinggiInFloat > 0)) {
|
||||||
|
val totalTinggiInches = (tinggiFtFloat * 12) + tinggiInFloat
|
||||||
|
bmi = (beratLbsFloat / totalTinggiInches.pow(2)) * 703
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bmi != null && umur.isNotBlank() && jenisKelamin != null) {
|
||||||
|
bmiResult = bmi
|
||||||
|
bmiCategory = when {
|
||||||
|
bmi < 18.5 -> {
|
||||||
|
bmiColor = errorColor; "Berat badan kurang"
|
||||||
|
}
|
||||||
|
bmi < 25 -> {
|
||||||
|
bmiColor = Color(0xFF4CAF50); "Berat badan normal"
|
||||||
|
}
|
||||||
|
bmi < 30 -> {
|
||||||
|
bmiColor = Color(0xFFFFC107); "Kelebihan berat badan"
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
bmiColor = errorContainerColor; "Obesitas"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reset() {
|
||||||
|
umur = ""; jenisKelamin = null; tinggiCm = ""; beratKg = ""
|
||||||
|
tinggiFt = ""; tinggiIn = ""; beratLbs = ""
|
||||||
|
bmiResult = null; bmiCategory = ""; bmiColor = surfaceVariantColor
|
||||||
|
}
|
||||||
|
|
||||||
|
val gradientBrush = Brush.verticalGradient(
|
||||||
|
colors = listOf(primaryColor.copy(alpha = 0.2f), backgroundColor)
|
||||||
|
)
|
||||||
|
|
||||||
|
Box(modifier = Modifier.fillMaxSize().background(gradientBrush)) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(16.dp)
|
||||||
|
.verticalScroll(rememberScrollState()), // Membuat Column bisa di-scroll
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
"Kalkulator BMI",
|
||||||
|
style = MaterialTheme.typography.headlineLarge,
|
||||||
|
color = onBackgroundColor
|
||||||
|
)
|
||||||
|
|
||||||
|
// --- UI UNTUK PILIHAN UNIT SYSTEM ---
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
|
Text("Metric (kg, cm)", color = if (unitSystem == UnitSystem.Metric) primaryColor else onBackgroundColor)
|
||||||
|
Spacer(Modifier.width(8.dp))
|
||||||
|
Switch(
|
||||||
|
checked = unitSystem == UnitSystem.USC,
|
||||||
|
onCheckedChange = {
|
||||||
|
unitSystem = if (it) UnitSystem.USC else UnitSystem.Metric
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Spacer(Modifier.width(8.dp))
|
||||||
|
Text("USC (lbs, ft, in)", color = if (unitSystem == UnitSystem.USC) primaryColor else onBackgroundColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
Card(
|
||||||
|
shape = RoundedCornerShape(16.dp),
|
||||||
|
elevation = CardDefaults.cardElevation(8.dp),
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Column(modifier = Modifier.padding(16.dp)) {
|
||||||
|
// --- Pilihan Jenis Kelamin (Tetap Sama) ---
|
||||||
|
Text("Jenis Kelamin", style = MaterialTheme.typography.bodyLarge, modifier = Modifier.padding(bottom = 8.dp))
|
||||||
|
// (Kode Row untuk jenis kelamin tidak berubah, jadi disingkat untuk kejelasan)
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
|
) {
|
||||||
|
val isLakiSelected = jenisKelamin == "Laki-laki"
|
||||||
|
Button(onClick={jenisKelamin="Laki-laki"},modifier=Modifier.weight(1f),colors=ButtonDefaults.buttonColors(containerColor=if(isLakiSelected)primaryColor else MaterialTheme.colorScheme.surface,contentColor=if(isLakiSelected)MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurface),border=BorderStroke(1.dp,if(isLakiSelected)primaryColor else MaterialTheme.colorScheme.outline)){Icon(Icons.Default.Male,"Laki-laki",modifier=Modifier.size(18.dp));Spacer(Modifier.width(8.dp));Text("Laki-laki")}
|
||||||
|
val isPerempuanSelected = jenisKelamin == "Perempuan"
|
||||||
|
Button(onClick={jenisKelamin="Perempuan"},modifier=Modifier.weight(1f),colors=ButtonDefaults.buttonColors(containerColor=if(isPerempuanSelected)primaryColor else MaterialTheme.colorScheme.surface,contentColor=if(isPerempuanSelected)MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurface),border=BorderStroke(1.dp,if(isPerempuanSelected)primaryColor else MaterialTheme.colorScheme.outline)){Icon(Icons.Default.Female,"Perempuan",modifier=Modifier.size(18.dp));Spacer(Modifier.width(8.dp));Text("Perempuan")}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
OutlinedTextField(value=umur,onValueChange={umur=it},label={Text("Umur")},leadingIcon={Icon(Icons.Default.CalendarToday,"Umur")},keyboardOptions=KeyboardOptions(keyboardType=KeyboardType.Number,imeAction=ImeAction.Next),singleLine=true,modifier=Modifier.fillMaxWidth())
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
// --- INPUT FIELD DINAMIS BERDASARKAN UNIT SYSTEM ---
|
||||||
|
if (unitSystem == UnitSystem.Metric) {
|
||||||
|
// Input untuk METRIC
|
||||||
|
OutlinedTextField(value=tinggiCm,onValueChange={tinggiCm=it},label={Text("Tinggi Badan (cm)")},leadingIcon={Icon(Icons.Default.Height,"Tinggi Badan")},keyboardOptions=KeyboardOptions(keyboardType=KeyboardType.Number,imeAction=ImeAction.Next),singleLine=true,modifier=Modifier.fillMaxWidth())
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
OutlinedTextField(value=beratKg,onValueChange={beratKg=it},label={Text("Berat Badan (kg)")},leadingIcon={Icon(Icons.Default.MonitorWeight,"Berat Badan")},keyboardOptions=KeyboardOptions(keyboardType=KeyboardType.Number,imeAction=ImeAction.Done),keyboardActions=KeyboardActions(onDone={calculateBmi()}),singleLine=true,modifier=Modifier.fillMaxWidth())
|
||||||
|
} else {
|
||||||
|
// Input untuk USC
|
||||||
|
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||||
|
OutlinedTextField(value=tinggiFt,onValueChange={tinggiFt=it},label={Text("Tinggi (ft)")},modifier=Modifier.weight(1f),keyboardOptions=KeyboardOptions(keyboardType=KeyboardType.Number,imeAction=ImeAction.Next),singleLine=true)
|
||||||
|
OutlinedTextField(value=tinggiIn,onValueChange={tinggiIn=it},label={Text("Tinggi (in)")},modifier=Modifier.weight(1f),keyboardOptions=KeyboardOptions(keyboardType=KeyboardType.Number,imeAction=ImeAction.Next),singleLine=true)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
OutlinedTextField(value=beratLbs,onValueChange={beratLbs=it},label={Text("Berat Badan (lbs)")},leadingIcon={Icon(Icons.Default.MonitorWeight,"Berat Badan")},keyboardOptions=KeyboardOptions(keyboardType=KeyboardType.Number,imeAction=ImeAction.Done),keyboardActions=KeyboardActions(onDone={calculateBmi()}),singleLine=true,modifier=Modifier.fillMaxWidth())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
|
Row(Modifier.fillMaxWidth(),horizontalArrangement=Arrangement.SpaceAround){Button(onClick={calculateBmi()},modifier=Modifier.weight(1f).height(50.dp)){Text("Hitung",fontSize=16.sp)};Spacer(Modifier.width(16.dp));Button(onClick={reset()},colors=ButtonDefaults.buttonColors(containerColor=secondaryColor),modifier=Modifier.weight(1f).height(50.dp)){Text("Ulang",fontSize=16.sp)}}
|
||||||
|
Spacer(modifier = Modifier.height(32.dp))
|
||||||
|
|
||||||
|
// Kartu Hasil (Tidak perlu diubah)
|
||||||
|
AnimatedVisibility(visible=bmiResult!=null,enter=fadeIn(animationSpec=tween(500))+slideInVertically(initialOffsetY={it/2},animationSpec=tween(500))){Card(shape=RoundedCornerShape(16.dp),colors=CardDefaults.cardColors(containerColor=bmiColor),modifier=Modifier.fillMaxWidth()){Column(modifier=Modifier.padding(24.dp),horizontalAlignment=Alignment.CenterHorizontally,verticalArrangement=Arrangement.Center){Text("Hasil untuk $jenisKelamin, Usia $umur Tahun",color=Color.White,style=MaterialTheme.typography.titleMedium);Spacer(Modifier.height(8.dp));Text(if(bmiResult!=null)"%.2f".format(bmiResult)else {
|
||||||
|
""
|
||||||
|
},color=Color.White,fontSize=48.sp,fontWeight=FontWeight.Bold);Spacer(Modifier.height(8.dp));Text(bmiCategory,color=Color.White,fontSize=20.sp,textAlign=TextAlign.Center,style=MaterialTheme.typography.bodyLarge)}}}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.weight(1f, fill = false).padding(32.dp)) // Spacer fleksibel
|
||||||
|
|
||||||
|
// Tombol Keluar (Tidak perlu diubah)
|
||||||
|
OutlinedButton(onClick={navController.navigate("login"){popUpTo(0)}},modifier=Modifier.fillMaxWidth(),border=BorderStroke(1.dp,primaryColor)){Icon(Icons.Default.ArrowBack,"Keluar",tint=primaryColor);Spacer(Modifier.width(8.dp));Text("Keluar",color=primaryColor)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user