Optimize dashboard environment cards

This commit is contained in:
zzh 2026-07-24 17:35:19 +08:00
parent cd96a88a95
commit bb096bb5b1

View File

@ -210,34 +210,72 @@ fun RoomSelector(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.horizontalScroll(rememberScrollState()), .horizontalScroll(rememberScrollState()),
horizontalArrangement = Arrangement.spacedBy(12.dp) horizontalArrangement = Arrangement.spacedBy(10.dp)
) { ) {
rooms.forEachIndexed { index, room -> rooms.forEachIndexed { index, room ->
val isSelected = index == selectedRoom val isSelected = index == selectedRoom
val shape = RoundedCornerShape(18.dp)
Box( Box(
modifier = Modifier modifier = Modifier
.width(128.dp) .widthIn(min = 92.dp)
.height(72.dp) .height(52.dp)
.clip(RoundedCornerShape(16.dp)) .clip(shape)
.background( .background(
if (isSelected) Color(0xFF00D1FF).copy(alpha = 0.22f) if (isSelected) {
else Color(0xFF1A1A1A).copy(alpha = 0.55f) Brush.linearGradient(
listOf(
Color(0xFF00D1FF).copy(alpha = 0.36f),
Color(0xFFB89CFF).copy(alpha = 0.28f)
)
)
} else {
Brush.linearGradient(
listOf(
Color.White.copy(alpha = 0.10f),
Color(0xFF121212).copy(alpha = 0.38f)
)
)
}
) )
.border( .border(
width = 1.dp, width = if (isSelected) 1.5.dp else 1.dp,
color = if (isSelected) Color(0xFF00D1FF) else Color.White.copy(alpha = 0.15f), color = if (isSelected) Color(0xFFA9F0FF) else Color.White.copy(alpha = 0.16f),
shape = RoundedCornerShape(16.dp) shape = shape
) )
.clickable { onRoomSelect(index) } .clickable { onRoomSelect(index) }
.padding(14.dp), .padding(horizontal = 16.dp),
contentAlignment = Alignment.CenterStart contentAlignment = Alignment.Center
) { ) {
Column { Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Box(
modifier = Modifier
.size(if (isSelected) 7.dp else 5.dp)
.clip(CircleShape)
.background(
if (isSelected) Color(0xFFA9F0FF)
else Color.White.copy(alpha = 0.36f)
)
)
Text( Text(
text = room, text = room,
color = Color.White, color = if (isSelected) Color.White else Color.White.copy(alpha = 0.72f),
fontSize = 16.sp, fontSize = 15.sp,
fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Medium fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Medium,
maxLines = 1
)
}
if (isSelected) {
Box(
modifier = Modifier
.align(Alignment.BottomCenter)
.width(28.dp)
.height(3.dp)
.clip(RoundedCornerShape(2.dp))
.background(Color(0xFFA9F0FF))
) )
} }
} }
@ -426,67 +464,87 @@ fun OverviewEnvironmentPanel(modifier: Modifier = Modifier) {
Box( Box(
modifier = modifier modifier = modifier
.clip(RoundedCornerShape(24.dp)) .clip(RoundedCornerShape(24.dp))
.background(Color(0xFF1A1A1A).copy(alpha = 0.55f)) .background(
Brush.linearGradient(
listOf(
Color(0xFF1A1A1A).copy(alpha = 0.64f),
Color(0xFF101820).copy(alpha = 0.48f)
)
)
)
.border( .border(
width = 1.dp, width = 1.dp,
color = Color.White.copy(alpha = 0.15f), color = Color.White.copy(alpha = 0.18f),
shape = RoundedCornerShape(24.dp) shape = RoundedCornerShape(24.dp)
) )
.padding(20.dp) .padding(16.dp)
) { ) {
Column( Column(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(12.dp) verticalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
Text( OverviewPanelHeader(
text = "环境总览", title = "环境总览",
fontWeight = FontWeight.Bold, subtitle = "全屋加权平均 · 综合环境水平",
color = Color.White, statusText = "舒适",
fontSize = 18.sp statusColor = Color(0xFF00E676)
) )
Text( Column(
text = "全屋加权平均 · 综合环境水平",
color = Color(0xFF9AA0A6),
fontSize = 12.sp
)
Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.weight(1f), .weight(1f),
horizontalArrangement = Arrangement.spacedBy(12.dp) verticalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
EnvironmentCard( Row(
icon = "🌡️", modifier = Modifier.weight(1f),
iconColor = Color(0xFF00E676), horizontalArrangement = Arrangement.spacedBy(8.dp)
value = "24.0", ) {
unit = "°C", EnvironmentCard(
label = "加权平均温度", icon = "🌡️",
modifier = Modifier.weight(1f).fillMaxHeight() iconColor = Color(0xFF00E676),
) name = "温度",
EnvironmentCard( value = "24.0",
icon = "💧", unit = "°C",
iconColor = Color(0xFF00E676), label = "全屋平均",
value = "65", status = "舒适",
unit = "%", modifier = Modifier.weight(1f).fillMaxHeight()
label = "加权平均湿度", )
modifier = Modifier.weight(1f).fillMaxHeight() EnvironmentCard(
) icon = "💧",
EnvironmentCard( iconColor = Color(0xFF4DD0E1),
icon = "😊", name = "湿度",
iconColor = Color(0xFF00E676), value = "65",
value = "420", unit = "%",
unit = "ppm", label = "全屋平均",
label = "加权平均 CO₂", status = "略湿",
modifier = Modifier.weight(1f).fillMaxHeight() modifier = Modifier.weight(1f).fillMaxHeight()
) )
EnvironmentCard( }
icon = "", Row(
iconColor = Color(0xFFA9F0FF), modifier = Modifier.weight(1f),
value = "0.18", horizontalArrangement = Arrangement.spacedBy(8.dp)
unit = "mg/m³", ) {
label = "加权平均 TVOC", EnvironmentCard(
modifier = Modifier.weight(1f).fillMaxHeight() icon = "",
) iconColor = Color(0xFF00E676),
name = "CO₂",
value = "420",
unit = "ppm",
label = "二氧化碳",
status = "清新",
modifier = Modifier.weight(1f).fillMaxHeight()
)
EnvironmentCard(
icon = "",
iconColor = Color(0xFFA9F0FF),
name = "TVOC",
value = "0.18",
unit = "mg/m³",
label = "挥发性有机物",
status = "正常",
modifier = Modifier.weight(1f).fillMaxHeight()
)
}
} }
} }
} }
@ -497,111 +555,196 @@ fun HealthSafetyPanel(modifier: Modifier = Modifier) {
Box( Box(
modifier = modifier modifier = modifier
.clip(RoundedCornerShape(24.dp)) .clip(RoundedCornerShape(24.dp))
.background(Color(0xFF1A1A1A).copy(alpha = 0.55f)) .background(
Brush.linearGradient(
listOf(
Color(0xFF1A1A1A).copy(alpha = 0.64f),
Color(0xFF1C1514).copy(alpha = 0.46f)
)
)
)
.border( .border(
width = 1.dp, width = 1.dp,
color = Color.White.copy(alpha = 0.15f), color = Color.White.copy(alpha = 0.18f),
shape = RoundedCornerShape(24.dp) shape = RoundedCornerShape(24.dp)
) )
.padding(20.dp) .padding(16.dp)
) { ) {
Column( Column(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(12.dp) verticalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
Text( OverviewPanelHeader(
text = "健康与安全", title = "健康与安全",
fontWeight = FontWeight.Bold, subtitle = "传感器2单点实测 · 最不利点状态",
color = Color.White, statusText = "需关注",
fontSize = 18.sp statusColor = Color(0xFFFFB74D)
)
Text(
text = "传感器2单点实测 · 最不利点状态",
color = Color(0xFF9AA0A6),
fontSize = 12.sp
) )
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.weight(1f), .weight(1f),
horizontalArrangement = Arrangement.spacedBy(12.dp) horizontalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
EnvironmentCard( Row(
icon = "💨", modifier = Modifier.weight(1.15f).fillMaxHeight(),
iconColor = Color(0xFFFFB74D), horizontalArrangement = Arrangement.spacedBy(8.dp)
value = "35", ) {
unit = "μg/m³", EnvironmentCard(
label = "PM2.5 · 传感器2", icon = "",
modifier = Modifier.weight(1f).fillMaxHeight() iconColor = Color(0xFFFFB74D),
) name = "PM2.5",
EnvironmentCard( value = "35",
icon = "⚠️", unit = "μg/m³",
iconColor = Color(0xFFFFB74D), label = "细颗粒物 · 传感器2",
value = "0.03", status = "",
unit = "mg/m³", modifier = Modifier.weight(1f).fillMaxHeight()
label = "甲醛 · 传感器2", )
modifier = Modifier.weight(1f).fillMaxHeight() EnvironmentCard(
) icon = "!",
CondensationMonitorCard(modifier = Modifier.weight(1.35f).fillMaxHeight()) iconColor = Color(0xFFFFB74D),
name = "甲醛",
value = "0.03",
unit = "mg/m³",
label = "HCHO · 传感器2",
status = "安全",
modifier = Modifier.weight(1f).fillMaxHeight()
)
}
CondensationMonitorCard(modifier = Modifier.weight(1f).fillMaxHeight())
} }
} }
} }
} }
@Composable
private fun OverviewPanelHeader(
title: String,
subtitle: String,
statusText: String,
statusColor: Color
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
Text(
text = title,
fontWeight = FontWeight.Bold,
color = Color.White,
fontSize = 16.sp
)
Text(
text = subtitle,
color = Color(0xFF9AA0A6),
fontSize = 10.sp,
maxLines = 1
)
}
Row(
modifier = Modifier
.clip(RoundedCornerShape(50))
.background(statusColor.copy(alpha = 0.14f))
.border(
width = 1.dp,
color = statusColor.copy(alpha = 0.42f),
shape = RoundedCornerShape(50)
)
.padding(horizontal = 8.dp, vertical = 4.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(5.dp)
) {
Box(
modifier = Modifier
.size(6.dp)
.clip(CircleShape)
.background(statusColor)
)
Text(
text = statusText,
color = statusColor,
fontSize = 11.sp,
fontWeight = FontWeight.SemiBold
)
}
}
}
@Composable @Composable
private fun CondensationMonitorCard(modifier: Modifier = Modifier) { private fun CondensationMonitorCard(modifier: Modifier = Modifier) {
Box( Box(
modifier = modifier modifier = modifier
.clip(RoundedCornerShape(20.dp)) .clip(RoundedCornerShape(20.dp))
.background(Color(0xFF00D1FF).copy(alpha = 0.12f)) .background(
Brush.linearGradient(
listOf(
Color(0xFF00D1FF).copy(alpha = 0.20f),
Color(0xFF121212).copy(alpha = 0.42f)
)
)
)
.border( .border(
width = 1.5.dp, width = 1.5.dp,
color = Color(0xFF00D1FF).copy(alpha = 0.75f), color = Color(0xFF00D1FF).copy(alpha = 0.75f),
shape = RoundedCornerShape(20.dp) shape = RoundedCornerShape(20.dp)
) )
.padding(16.dp) .padding(horizontal = 10.dp, vertical = 8.dp)
) { ) {
Column( Row(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.SpaceBetween verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
Row( Box(
modifier = Modifier.fillMaxWidth(), modifier = Modifier
horizontalArrangement = Arrangement.SpaceBetween, .size(28.dp)
verticalAlignment = Alignment.Top .clip(RoundedCornerShape(9.dp))
.background(Color(0xFF00D1FF).copy(alpha = 0.18f)),
contentAlignment = Alignment.Center
) { ) {
Text(text = "🧱", fontSize = 22.sp) Text(text = "", fontSize = 14.sp, color = Color(0xFFA9F0FF))
Box(
modifier = Modifier
.size(8.dp)
.clip(CircleShape)
.background(Color(0xFF00E676))
)
} }
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { Column(
Text( modifier = Modifier.weight(1f),
text = "18.6", verticalArrangement = Arrangement.spacedBy(1.dp)
fontSize = 36.sp, ) {
fontWeight = FontWeight.Light,
color = Color.White
)
Text(
text = "°C",
fontSize = 14.sp,
color = Color(0xFF9AA0A6)
)
Text( Text(
text = "防结露监控", text = "防结露监控",
fontSize = 12.sp,
fontWeight = FontWeight.Bold,
color = Color(0xFF00D1FF)
)
Text(
text = "墙温 · 安全",
fontSize = 11.sp, fontSize = 11.sp,
color = Color(0xFF9AA0A6) fontWeight = FontWeight.Bold,
color = Color.White,
maxLines = 1
) )
Row(
verticalAlignment = Alignment.Bottom,
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
Text(
text = "18.6",
fontSize = 18.sp,
fontWeight = FontWeight.Light,
color = Color.White
)
Text(
text = "°C",
fontSize = 9.sp,
color = Color(0xFF9AA0A6),
modifier = Modifier.padding(bottom = 3.dp)
)
}
} }
Text(
text = "安全",
color = Color(0xFF00E676),
fontSize = 9.sp,
fontWeight = FontWeight.SemiBold,
modifier = Modifier
.clip(RoundedCornerShape(50))
.background(Color(0xFF00E676).copy(alpha = 0.14f))
.padding(horizontal = 6.dp, vertical = 2.dp)
)
} }
} }
} }
@ -1921,6 +2064,7 @@ fun AirConditionerCard(
EnvironmentCard( EnvironmentCard(
icon = "🌡️", icon = "🌡️",
iconColor = Color(0xFF00E676), iconColor = Color(0xFF00E676),
name = "温度",
value = "${currentTemp.value}", value = "${currentTemp.value}",
unit = "°C", unit = "°C",
label = "TEMPERATURE", label = "TEMPERATURE",
@ -1933,6 +2077,7 @@ fun AirConditionerCard(
EnvironmentCard( EnvironmentCard(
icon = "💧", icon = "💧",
iconColor = Color(0xFF00E676), iconColor = Color(0xFF00E676),
name = "湿度",
value = "${humidity.value}", value = "${humidity.value}",
unit = "%", unit = "%",
label = "HUMIDITY", label = "HUMIDITY",
@ -1945,6 +2090,7 @@ fun AirConditionerCard(
EnvironmentCard( EnvironmentCard(
icon = "💨", icon = "💨",
iconColor = Color(0xFFFFB74D), iconColor = Color(0xFFFFB74D),
name = "PM2.5",
value = "${pm25.value}", value = "${pm25.value}",
unit = "μg/m³", unit = "μg/m³",
label = "PM 2.5", label = "PM 2.5",
@ -1957,6 +2103,7 @@ fun AirConditionerCard(
EnvironmentCard( EnvironmentCard(
icon = "😊", icon = "😊",
iconColor = Color(0xFF00E676), iconColor = Color(0xFF00E676),
name = "CO₂",
value = "${co2.value}", value = "${co2.value}",
unit = "ppm", unit = "ppm",
label = "CO2", label = "CO2",
@ -1973,9 +2120,11 @@ fun AirConditionerCard(
private fun EnvironmentCard( private fun EnvironmentCard(
icon: String, icon: String,
iconColor: Color, iconColor: Color,
name: String,
value: String, value: String,
unit: String, unit: String,
label: String, label: String,
status: String = "",
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
Box( Box(
@ -1984,79 +2133,89 @@ private fun EnvironmentCard(
.background( .background(
Brush.linearGradient( Brush.linearGradient(
listOf( listOf(
Color.Black.copy(alpha = 0.5f), Color.White.copy(alpha = 0.10f),
Color.Black.copy(alpha = 0.4f) Color.Black.copy(alpha = 0.42f)
) )
) )
) )
.border( .border(
width = 0.5.dp, width = 1.dp,
color = Color.White.copy(alpha = 0.15f), color = Color.White.copy(alpha = 0.14f),
shape = RoundedCornerShape(20.dp) shape = RoundedCornerShape(20.dp)
) )
.padding(16.dp) .padding(horizontal = 10.dp, vertical = 8.dp)
) { ) {
Column( Row(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.SpaceBetween verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
// 顶部:图标和指示灯 Box(
Row( modifier = Modifier
modifier = Modifier.fillMaxWidth(), .size(28.dp)
horizontalArrangement = Arrangement.SpaceBetween, .clip(RoundedCornerShape(9.dp))
verticalAlignment = Alignment.Top .background(iconColor.copy(alpha = 0.16f))
.border(
width = 1.dp,
color = iconColor.copy(alpha = 0.24f),
shape = RoundedCornerShape(9.dp)
),
contentAlignment = Alignment.Center
) { ) {
// 图标 Text(
Box( text = icon,
modifier = Modifier fontSize = 14.sp,
.size(44.dp) color = iconColor
.clip(RoundedCornerShape(12.dp))
.background(iconColor.copy(alpha = 0.15f)),
contentAlignment = Alignment.Center
) {
Text(
text = icon,
fontSize = 22.sp
)
}
// 指示灯
Box(
modifier = Modifier
.size(8.dp)
.clip(RoundedCornerShape(4.dp))
.background(iconColor)
) )
} }
// 中间:数值
Column( Column(
verticalArrangement = Arrangement.spacedBy(4.dp) modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(1.dp)
) { ) {
Text(
text = name,
fontSize = 11.sp,
fontWeight = FontWeight.Bold,
color = Color.White,
maxLines = 1
)
Row( Row(
verticalAlignment = Alignment.Bottom, verticalAlignment = Alignment.Bottom,
horizontalArrangement = Arrangement.spacedBy(4.dp) horizontalArrangement = Arrangement.spacedBy(3.dp)
) { ) {
Text( Text(
text = value, text = value,
fontSize = 36.sp, fontSize = 18.sp,
fontWeight = FontWeight.Light, fontWeight = FontWeight.Light,
color = Color.White color = Color.White
) )
Text( Text(
text = unit, text = unit,
fontSize = 14.sp, fontSize = 9.sp,
color = Color(0xFF9AA0A6), color = Color(0xFF9AA0A6),
modifier = Modifier.padding(bottom = 6.dp) modifier = Modifier.padding(bottom = 3.dp)
) )
} }
}
// 底部:标签
if (status.isNotEmpty()) {
Text( Text(
text = label, text = status,
fontSize = 11.sp, color = iconColor,
color = Color(0xFF9AA0A6), fontSize = 9.sp,
letterSpacing = 0.5.sp fontWeight = FontWeight.SemiBold,
modifier = Modifier
.clip(RoundedCornerShape(50))
.background(iconColor.copy(alpha = 0.12f))
.padding(horizontal = 6.dp, vertical = 2.dp)
)
} else {
Box(
modifier = Modifier
.size(7.dp)
.clip(RoundedCornerShape(4.dp))
.background(iconColor)
) )
} }
} }