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

156
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,19 +147,26 @@ 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
) { ) {
Image(
painterResource(background),
contentDescription = null,
modifier = Modifier.fillMaxSize()
)
Row(modifier = Modifier.padding(top = 20.dp, start = 20.dp)) {
Text( Text(
text = title, text = title,
fontSize = 18.sp, fontSize = 24.sp,
color = Color.White, color = Color.White,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold,
) )
} }
} }
}
} }
@Composable @Composable
@ -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,11 +199,18 @@ 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)
) { ) {
Box(modifier = Modifier.fillMaxSize()){
Image(
painterResource(Res.drawable.bg_exercise_history),
contentDescription = null,
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Crop
)
Column( Column(
modifier = Modifier.padding(16.dp) modifier = Modifier.padding(14.dp)
) { ) {
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@ -188,12 +221,12 @@ fun ExerciseRecordsSection() {
text = "运动记录", text = "运动记录",
fontSize = 16.sp, fontSize = 16.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = Color(0xFF666666) color = Color(0xffffffff)
) )
Text( Text(
text = "查看更多", text = "查看更多",
fontSize = 14.sp, fontSize = 14.sp,
color = Color(0xFF9C27B0) color = Color(0xffffffff)
) )
} }
@ -202,13 +235,16 @@ fun ExerciseRecordsSection() {
// 户外跑步记录 // 户外跑步记录
ExerciseRecordItem( ExerciseRecordItem(
iconColor = Color(0xFF2196F3), iconColor = Color(0xFF2196F3),
iconRes = Res.drawable.ic_running,
title = "户外跑步", title = "户外跑步",
distance = "2.85公里", distance = "2.85公里",
time = "00:20:36", time = "00:20:36",
pace = "7'59\"公里" pace = "7'59\"公里"
) )
Spacer(modifier = Modifier.height(12.dp)) Row(modifier = Modifier.height(16.dp).padding(start = 65.dp), verticalAlignment = Alignment.CenterVertically){
Box(modifier = Modifier.background(Color.White).height(1.dp).fillMaxWidth())
}
// 自由训练记录 // 自由训练记录
ExerciseRecordItem( ExerciseRecordItem(
@ -216,15 +252,19 @@ fun ExerciseRecordsSection() {
title = "自由训练", title = "自由训练",
distance = "161千卡", distance = "161千卡",
time = "00:57:06", time = "00:57:06",
pace = "104次/分钟" pace = "104次/分钟",
iconRes = Res.drawable.ic_free
) )
} }
} }
}
} }
@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,9 +321,11 @@ 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)
) { ) {
Box(modifier = Modifier.fillMaxSize()){
Image(painterResource(Res.drawable.bg_score),contentDescription = null, modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Crop)
Column( Column(
modifier = Modifier.padding(16.dp) modifier = Modifier.padding(16.dp)
) { ) {
@ -305,7 +342,7 @@ fun ComprehensiveScoreSection() {
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(200.dp), .height(140.dp),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
CircularScoreChart(score = 75) CircularScoreChart(score = 75)
@ -342,29 +379,33 @@ 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