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. 320
      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

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

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