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