Browse Source

fix: exercise history style

main
AnranYus 1 month ago
parent
commit
8692cb06e2
  1. BIN
      composeApp/src/commonMain/composeResources/drawable/bg_exercise_history.png
  2. BIN
      composeApp/src/commonMain/composeResources/drawable/bg_score.png
  3. BIN
      composeApp/src/commonMain/composeResources/drawable/ic_exercise_riding.png
  4. BIN
      composeApp/src/commonMain/composeResources/drawable/ic_exercise_running.png
  5. BIN
      composeApp/src/commonMain/composeResources/drawable/ic_exercise_swimming.png
  6. BIN
      composeApp/src/commonMain/composeResources/drawable/ic_free.png
  7. BIN
      composeApp/src/commonMain/composeResources/drawable/ic_running.png
  8. 322
      composeApp/src/commonMain/kotlin/com/whitefish/app/ui/home/exercise/ExerciseScreen.kt

BIN
composeApp/src/commonMain/composeResources/drawable/bg_exercise_history.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
composeApp/src/commonMain/composeResources/drawable/bg_score.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
composeApp/src/commonMain/composeResources/drawable/ic_exercise_riding.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

BIN
composeApp/src/commonMain/composeResources/drawable/ic_exercise_running.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
composeApp/src/commonMain/composeResources/drawable/ic_exercise_swimming.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

BIN
composeApp/src/commonMain/composeResources/drawable/ic_free.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
composeApp/src/commonMain/composeResources/drawable/ic_running.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 B

322
composeApp/src/commonMain/kotlin/com/whitefish/app/ui/home/exercise/ExerciseScreen.kt

@ -1,6 +1,7 @@
package com.whitefish.app.ui.home.exercise
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
@ -17,10 +18,24 @@ import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.jetbrains.compose.resources.DrawableResource
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.ui.tooling.preview.Preview
import ringappkmp.composeapp.generated.resources.Res
import ringappkmp.composeapp.generated.resources.bg
import ringappkmp.composeapp.generated.resources.bg_exercise_history
import ringappkmp.composeapp.generated.resources.bg_exercise_target
import ringappkmp.composeapp.generated.resources.bg_score
import ringappkmp.composeapp.generated.resources.ic_exercise_riding
import ringappkmp.composeapp.generated.resources.ic_exercise_running
import ringappkmp.composeapp.generated.resources.ic_exercise_swimming
import ringappkmp.composeapp.generated.resources.ic_free
import ringappkmp.composeapp.generated.resources.ic_running
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -96,22 +111,22 @@ fun ExerciseTypeCards() {
item {
ExerciseTypeCard(
title = "跑步",
gradient = listOf(Color(0xFF4FC3F7), Color(0xFF29B6F6)),
modifier = Modifier.size(160.dp, 120.dp)
modifier = Modifier.size(154.dp, 154.dp),
background = Res.drawable.ic_exercise_running
)
}
item {
ExerciseTypeCard(
title = "骑行",
gradient = listOf(Color(0xFFFFB74D), Color(0xFFFF9800)),
modifier = Modifier.size(160.dp, 120.dp)
background = Res.drawable.ic_exercise_riding,
modifier = Modifier.size(154.dp, 154.dp)
)
}
item {
ExerciseTypeCard(
title = "游泳",
gradient = listOf(Color(0xFF4DD0E1), Color(0xFF00BCD4)),
modifier = Modifier.size(160.dp, 120.dp)
background = Res.drawable.ic_exercise_swimming,
modifier = Modifier.size(154.dp, 154.dp)
)
}
}
@ -120,7 +135,7 @@ fun ExerciseTypeCards() {
@Composable
fun ExerciseTypeCard(
title: String,
gradient: List<Color>,
background: DrawableResource,
modifier: Modifier = Modifier
) {
Card(
@ -132,17 +147,24 @@ fun ExerciseTypeCard(
modifier = Modifier
.fillMaxSize()
.background(
Brush.linearGradient(gradient),
Color.Transparent,
RoundedCornerShape(16.dp)
),
contentAlignment = Alignment.Center
contentAlignment = Alignment.TopStart
) {
Text(
text = title,
fontSize = 18.sp,
color = Color.White,
fontWeight = FontWeight.Bold
Image(
painterResource(background),
contentDescription = null,
modifier = Modifier.fillMaxSize()
)
Row(modifier = Modifier.padding(top = 20.dp, start = 20.dp)) {
Text(
text = title,
fontSize = 24.sp,
color = Color.White,
fontWeight = FontWeight.Bold,
)
}
}
}
}
@ -158,7 +180,11 @@ fun AddExerciseButton() {
shape = RoundedCornerShape(16.dp),
elevation = CardDefaults.cardElevation(10.dp)
) {
Row(modifier = Modifier.fillMaxSize(),verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center) {
Row(
modifier = Modifier.fillMaxSize(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Text(
text = "+ 添加运动记录",
fontSize = 16.sp,
@ -173,58 +199,72 @@ fun AddExerciseButton() {
fun ExerciseRecordsSection() {
Card(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(Color.White.copy(alpha = 0.9f))
shape = RoundedCornerShape(24.dp),
colors = CardDefaults.cardColors(containerColor = Color.Transparent)
) {
Column(
modifier = Modifier.padding(16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
Box(modifier = Modifier.fillMaxSize()){
Image(
painterResource(Res.drawable.bg_exercise_history),
contentDescription = null,
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Crop
)
Column(
modifier = Modifier.padding(14.dp)
) {
Text(
text = "运动记录",
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
color = Color(0xFF666666)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "运动记录",
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
color = Color(0xffffffff)
)
Text(
text = "查看更多",
fontSize = 14.sp,
color = Color(0xffffffff)
)
}
Spacer(modifier = Modifier.height(16.dp))
// 户外跑步记录
ExerciseRecordItem(
iconColor = Color(0xFF2196F3),
iconRes = Res.drawable.ic_running,
title = "户外跑步",
distance = "2.85公里",
time = "00:20:36",
pace = "7'59\"公里"
)
Text(
text = "查看更多",
fontSize = 14.sp,
color = Color(0xFF9C27B0)
Row(modifier = Modifier.height(16.dp).padding(start = 65.dp), verticalAlignment = Alignment.CenterVertically){
Box(modifier = Modifier.background(Color.White).height(1.dp).fillMaxWidth())
}
// 自由训练记录
ExerciseRecordItem(
iconColor = Color(0xFF4CAF50),
title = "自由训练",
distance = "161千卡",
time = "00:57:06",
pace = "104次/分钟",
iconRes = Res.drawable.ic_free
)
}
Spacer(modifier = Modifier.height(16.dp))
// 户外跑步记录
ExerciseRecordItem(
iconColor = Color(0xFF2196F3),
title = "户外跑步",
distance = "2.85公里",
time = "00:20:36",
pace = "7'59\"公里"
)
Spacer(modifier = Modifier.height(12.dp))
// 自由训练记录
ExerciseRecordItem(
iconColor = Color(0xFF4CAF50),
title = "自由训练",
distance = "161千卡",
time = "00:57:06",
pace = "104次/分钟"
)
}
}
}
@Composable
fun ExerciseRecordItem(
iconColor: Color,
iconRes: DrawableResource,
title: String,
distance: String,
time: String,
@ -237,16 +277,11 @@ fun ExerciseRecordItem(
// 运动图标占位
Box(
modifier = Modifier
.size(40.dp)
.size(50.dp)
.background(iconColor, CircleShape),
contentAlignment = Alignment.Center
) {
Text(
text = title.first().toString(),
color = Color.White,
fontSize = 16.sp,
fontWeight = FontWeight.Bold
)
Image(painterResource(iconRes),contentDescription = null)
}
Spacer(modifier = Modifier.width(12.dp))
@ -254,28 +289,28 @@ fun ExerciseRecordItem(
Column(modifier = Modifier.weight(1f)) {
Text(
text = title,
fontSize = 16.sp,
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
color = Color(0xFF333333)
color = Color(0xEFffffff),
)
Spacer(modifier = Modifier.height(4.dp))
Row {
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween) {
Text(
text = distance,
fontSize = 14.sp,
color = Color(0xFF666666)
fontSize = 12.sp,
color = Color(0xFFffffff)
)
Spacer(modifier = Modifier.width(16.dp))
Text(
text = time,
fontSize = 14.sp,
color = Color(0xFF666666)
fontSize = 12.sp,
color = Color(0xFFffffff)
)
Spacer(modifier = Modifier.width(16.dp))
Text(
text = pace,
fontSize = 14.sp,
color = Color(0xFF666666)
fontSize = 12.sp,
color = Color(0xFFffffff)
)
}
}
@ -286,59 +321,62 @@ fun ExerciseRecordItem(
fun ComprehensiveScoreSection() {
Card(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(Color.White.copy(alpha = 0.9f))
shape = RoundedCornerShape(24.dp),
colors = CardDefaults.cardColors(Color.Transparent)
) {
Column(
modifier = Modifier.padding(16.dp)
) {
Text(
text = "综合评分",
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
color = Color(0xFF333333)
)
Spacer(modifier = Modifier.height(20.dp))
// 圆形评分图表
Box(
modifier = Modifier
.fillMaxWidth()
.height(200.dp),
contentAlignment = Alignment.Center
Box(modifier = Modifier.fillMaxSize()){
Image(painterResource(Res.drawable.bg_score),contentDescription = null, modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Crop)
Column(
modifier = Modifier.padding(16.dp)
) {
CircularScoreChart(score = 75)
}
Text(
text = "综合评分",
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
color = Color(0xFF333333)
)
Spacer(modifier = Modifier.height(20.dp))
Spacer(modifier = Modifier.height(20.dp))
// 评估指标
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
ScoreIndicator(
label = "活动小时数得分",
value = "",
progress = 0.8f,
color = Color(0xFFFF6B6B)
)
ScoreIndicator(
label = "有氧活动评估",
value = "",
progress = 0.85f,
color = Color(0xFF4ECDC4)
)
ScoreIndicator(
label = "运动强度审评估",
value = "",
progress = 0.95f,
color = Color(0xFF45B7D1)
)
ScoreIndicator(
label = "运动强度效率评估",
value = "",
progress = 0.9f,
color = Color(0xFF96CEB4)
)
// 圆形评分图表
Box(
modifier = Modifier
.fillMaxWidth()
.height(140.dp),
contentAlignment = Alignment.Center
) {
CircularScoreChart(score = 75)
}
Spacer(modifier = Modifier.height(20.dp))
// 评估指标
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
ScoreIndicator(
label = "活动小时数得分",
value = "",
progress = 0.8f,
color = Color(0xFFFF6B6B)
)
ScoreIndicator(
label = "有氧活动评估",
value = "",
progress = 0.85f,
color = Color(0xFF4ECDC4)
)
ScoreIndicator(
label = "运动强度审评估",
value = "",
progress = 0.95f,
color = Color(0xFF45B7D1)
)
ScoreIndicator(
label = "运动强度效率评估",
value = "",
progress = 0.9f,
color = Color(0xFF96CEB4)
)
}
}
}
}
@ -346,25 +384,28 @@ fun ComprehensiveScoreSection() {
@Composable
fun CircularScoreChart(score: Int) {
Box(contentAlignment = Alignment.Center) {
Canvas(modifier = Modifier.size(120.dp)) {
Box(contentAlignment = Alignment.BottomCenter) {
Canvas(modifier = Modifier.size(250.dp, 125.dp)) {
val strokeWidth = 12.dp.toPx()
val radius = (size.minDimension - strokeWidth) / 2
val center = Offset(size.width / 2, size.height / 2)
val radius = (size.width - strokeWidth) / 2
val center = Offset(size.width / 2, size.height)
// 背景圆
drawCircle(
// 背景
drawArc(
color = Color(0xFFE0E0E0),
radius = radius,
center = center,
style = Stroke(strokeWidth)
startAngle = 180f,
sweepAngle = 180f,
useCenter = false,
style = Stroke(strokeWidth),
topLeft = Offset(center.x - radius, center.y - radius),
size = Size(radius * 2, radius * 2)
)
// 进度圆弧
val sweepAngle = (score / 100f) * 360f
// 进度圆弧
val sweepAngle = (score / 100f) * 180f
drawArc(
color = Color(0xFF5E35B1),
startAngle = -90f,
startAngle = 180f,
sweepAngle = sweepAngle,
useCenter = false,
style = Stroke(strokeWidth, cap = StrokeCap.Round),
@ -373,7 +414,10 @@ fun CircularScoreChart(score: Int) {
)
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(bottom = 8.dp)
) {
Text(
text = score.toString(),
fontSize = 36.sp,
@ -437,8 +481,8 @@ fun ScoreIndicator(
fun InsightSection() {
Card(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(Color(0xFF5E35B1))
shape = RoundedCornerShape(24.dp),
colors = CardDefaults.cardColors(Color(0x80352764))
) {
Column(
modifier = Modifier.padding(16.dp)
@ -460,4 +504,10 @@ fun InsightSection() {
)
}
}
}
}
@Preview
@Composable
fun ExerciseScreenPreview() {
ExerciseScreen()
}
Loading…
Cancel
Save