Этот код рассчитывает количество воды, которое человек должен выпивать ежедневно. и когда вы нажимаете кнопку, вода из полной бутылки убавляется.
Собственно, в программе все работает четко, но при первом нажатии уровень воды в результате нажатия не меняется. После первого нажатия все работает нормально. Я не могу справиться с этим, ты можешь мне помочь?
package com.example.diettrackingapp.home
import android.widget.Toast
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.animateIntAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.clipPath
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.diettrackingapp.firebase.PatientViewModel
@Composable
fun WaterScreen() {
val context = LocalContext.current
var totalWaterAmount by remember { mutableStateOf(0) }
var usedWaterAmount by remember { mutableStateOf(0) }
val weight = 70
totalWaterAmount = (weight * 35)
val configuration = LocalConfiguration.current
val screenWidth = configuration.screenWidthDp.dp
Column(
modifier = Modifier
.width(screenWidth * 0.4f),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top
) {
Spacer(modifier = Modifier.height(25.dp))
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
WaterBottle(
modifier = Modifier
.width(screenWidth * 0.3f)
.height(screenWidth * 0.6f),
totalWaterAmount = totalWaterAmount,
unit = "ml",
usedWaterAmount = usedWaterAmount
)
Spacer(modifier = Modifier.height(10.dp))
Text(text = "Total:$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)
}
}
}
вы не можете запустить его правильно, потому что у вас нет подключения к моей базе данных. Я проверю это, мне очень жаль. Я изменю это.
Проблема в крышке бутылки, попробуйте увеличить значение UsedWaterAmount с 200 до 400, вы увидите результат.
зачем мне его увеличивать? Всегда есть математическое решение. Это было похоже на отговорку. Я так и сделал сначала, но кто-то решил проблему.
Регулирует путь бутылки и логику рисования воды с помощью capHeightRatio
@Composable
fun WaterScreen() {
val context = LocalContext.current
var usedWaterAmount by remember { mutableStateOf(0) }
val weight = 70
val totalWaterAmount = remember { weight * 35 }
val configuration = LocalConfiguration.current
val screenWidth = configuration.screenWidthDp.dp
Column(
modifier = Modifier
.width(screenWidth * 0.4f),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top
) {
Spacer(modifier = Modifier.height(25.dp))
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
WaterBottle(
modifier = Modifier
.width(screenWidth * 0.3f)
.height(screenWidth * 0.6f),
totalWaterAmount = totalWaterAmount,
unit = "ml",
usedWaterAmount = usedWaterAmount
)
Spacer(modifier = Modifier.height(10.dp))
Text(text = "Total: $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
// Adjust the starting position below the cap
val capHeightRatio = 0.1f // Adjust this value based on your cap height
val bodyStartY = height * capHeightRatio
// Draw bottle body
val bottleBodyPath = Path().apply {
moveTo(width * 0.3f, bodyStartY)
lineTo(width * 0.3f, bodyStartY + height * 0.1f)
quadraticBezierTo(0f, bodyStartY + height * 0.2f, 0f, bodyStartY + height * 0.3f)
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, bodyStartY + height * 0.3f)
quadraticBezierTo(width, bodyStartY + height * 0.2f, width * 0.7f, bodyStartY + height * 0.1f)
lineTo(width * 0.7f, bodyStartY)
close()
}
clipPath(bottleBodyPath) {
drawRect(color = bottleColor, size = size)
val waterWavesYPosition = bodyStartY + waterPercentage * (height - bodyStartY)
val waterPath = Path().apply {
moveTo(0f, waterWavesYPosition)
lineTo(size.width, waterWavesYPosition)
lineTo(size.width, size.height)
lineTo(0f, size.height)
close()
}
drawPath(waterPath, waterColor)
}
// Draw cap outside the clipping
val capWidth = size.width * 0.55f
val capHeight = height * capHeightRatio
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(SpanStyle(color = Color.Black, fontSize = fontSize * 2)) {
append(usedWaterAnimation.toString())
}
withStyle(SpanStyle(color = Color.Black, fontSize = fontSize)) {
append(" ")
append(unit)
}
}
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text(text = text)
}
}
}
У меня проблемы с запуском вашего кода. Можете ли вы отредактировать свой вопрос и удалить весь код, который не нужен для воспроизведения проблемы? Пожалуйста, предоставьте минимально воспроизводимый пример.