This code calculates the amount of water a person should drink daily. and as you click the button, it reduces the water from the full bottle.
Actually, everything in the program works clearly, but on the first click, the water level does not change as a result of the click. After the first click everything works normally. I can’t overcome this, can you help me?
@Composable
fun WaterScreen(email: String, patientViewModel: PatientViewModel = viewModel()) {
val context = LocalContext.current
var totalWaterAmount by remember { mutableStateOf(0) }
var usedWaterAmount by remember { mutableStateOf(0) }
LaunchedEffect(email) {
patientViewModel.fetchPatientByEmail(email)
}
val patient by patientViewModel.patient.collectAsState()
LaunchedEffect(patient) {
patient?.let {
totalWaterAmount = (it.weight * 35).toInt()
}
}
val configuration = LocalConfiguration.current
val screenWidth = configuration.screenWidthDp.dp
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.Top
) {
Spacer(modifier = Modifier.height(25.dp))
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
WaterBottle(
modifier = Modifier
.width(screenWidth * 0.40f)
.height(screenWidth * 0.7f),
totalWaterAmount = totalWaterAmount,
unit = "ml",
usedWaterAmount = usedWaterAmount
)
Spacer(modifier = Modifier.height(10.dp))
Text(text = "Total amount is $totalWaterAmount ml")
Button(onClick = {
if (usedWaterAmount < totalWaterAmount) usedWaterAmount += 200 else Toast.makeText(
context, "Bottle is Empty", Toast.LENGTH_LONG
).show()
}) {
Text(text = "Drink")
}
}
}
}
@Composable
fun WaterBottle(
modifier: Modifier,
totalWaterAmount: Int,
unit: String,
usedWaterAmount: Int,
waterColor: Color = Color(0xFF1F97F8),
bottleColor: Color = Color.White,
capColor: Color = Color(0xFF01355F)
) {
val waterPercentage by animateFloatAsState(
targetValue = if (totalWaterAmount > 0) usedWaterAmount.toFloat() / totalWaterAmount.toFloat() else 0f,
animationSpec = tween(1000), label = ""
)
val usedWaterAnimation by animateIntAsState(
targetValue = usedWaterAmount, animationSpec = tween(1000), label = ""
)
Box(
modifier = modifier.clip(RoundedCornerShape(10.dp)).background(Color(0xFFFDF7BA)).padding(10.dp)
) {
Canvas(modifier = Modifier.fillMaxSize()) {
val width = size.width
val height = size.height
val capWidth = size.width * 0.55f
val capHeight = size.height * 0.08f
val bottleBodyPath = Path().apply {
moveTo(width * 0.3f, height * 0.1f)
lineTo(
width * 0.3f, height * 0.2f
)
quadraticBezierTo(
0f, height * 0.3f, 0f, height * 0.4f
)
lineTo(
0f, height * 0.95f
)
quadraticBezierTo(
0f, height, width * 0.05f, height
)
lineTo(
width * 0.95f, height
)
quadraticBezierTo(
width, height, width, height * 0.95f
)
lineTo(
width, height * 0.4f
)
quadraticBezierTo(
width, height * 0.3f, width * 0.7f, height * 0.2f
)
lineTo(
width * 0.7f, height * 0.1f
)
close()
}
clipPath(
bottleBodyPath
) {
drawRect(
color = bottleColor, size = size
)
val waterWavesYPosition = waterPercentage * size.height
val waterPath = Path().apply {
moveTo(0f, waterWavesYPosition)
lineTo(
size.width, waterWavesYPosition
)
lineTo(
size.width, size.height
)
lineTo(
0f, size.height
)
close()
}
drawPath(
waterPath, waterColor
)
}
drawRoundRect(
color = capColor,
size = Size(capWidth, capHeight),
topLeft = Offset(size.width / 2 - capWidth / 2f, 0f),
cornerRadius = CornerRadius(45f, 45f)
)
}
val fontSize = with(LocalConfiguration.current) { screenWidthDp * 0.03 }.sp
val text = buildAnnotatedString {
withStyle(
SpanStyle(
color = Color.Black,
fontSize = fontSize
)
) {
append("Drunk Water:n")
}
withStyle(
style = SpanStyle(
color = Color.Black,
fontSize = fontSize * 2
)
) {
append(usedWaterAnimation.toString())
}
withStyle(
style = SpanStyle(
color = Color.Black,
fontSize = fontSize
)
) {
append(" ")
append(unit)
}
}
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(text = text)
}
}
}