From 7c8125f1824165a0984485689332fd5db0679d81 Mon Sep 17 00:00:00 2001 From: zzh Date: Wed, 26 Nov 2025 11:23:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=8A=B6=E6=80=81=E6=A0=8F?= =?UTF-8?q?=E5=92=8C=E5=AF=BC=E8=88=AA=E6=A0=8F=E9=9A=90=E8=97=8F=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/smarthome/MainActivity.kt | 65 +++++- .../com/example/smarthome/ui/MainScaffold.kt | 199 ++++++++++++++---- app/src/main/res/layout/activity_main.xml | 4 +- 3 files changed, 222 insertions(+), 46 deletions(-) diff --git a/app/src/main/java/com/example/smarthome/MainActivity.kt b/app/src/main/java/com/example/smarthome/MainActivity.kt index 5988570..3ce39da 100644 --- a/app/src/main/java/com/example/smarthome/MainActivity.kt +++ b/app/src/main/java/com/example/smarthome/MainActivity.kt @@ -21,20 +21,25 @@ import androidx.compose.foundation.layout.Box import androidx.compose.ui.unit.dp import com.example.smarthome.ui.MainScaffold import androidx.compose.ui.platform.ComposeView +import androidx.compose.foundation.Image +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.layout.ContentScale +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.systemBarsPadding class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - WindowCompat.setDecorFitsSystemWindows(window, true) + + // 隐藏状态栏和导航栏 + hideStatusBar() setContentView(R.layout.activity_main) val composeView = findViewById(R.id.composeView) composeView.setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) composeView.setContent { SmartHomeTheme { - Surface(modifier = Modifier.fillMaxSize(), color = Color(0xFF121212)) { - AppRoot() - } + AppRoot() } } @@ -47,6 +52,37 @@ class MainActivity : ComponentActivity() { .setBlurRadius(20f) } + private fun hideStatusBar() { + // 设置全屏模式,让内容延伸到系统栏区域 + WindowCompat.setDecorFitsSystemWindows(window, false) + + // 设置全屏标志 + window.setFlags( + android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN, + android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN + ) + + // 设置状态栏和导航栏为透明 + window.statusBarColor = android.graphics.Color.TRANSPARENT + window.navigationBarColor = android.graphics.Color.TRANSPARENT + + // 隐藏状态栏和导航栏 + window.decorView.systemUiVisibility = ( + android.view.View.SYSTEM_UI_FLAG_FULLSCREEN + or android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + or android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE + or android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + or android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + or android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + ) + + // 支持刘海屏设备 + val lp = window.attributes + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) { + lp.layoutInDisplayCutoutMode = android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES + } + window.attributes = lp + } } @Composable @@ -78,7 +114,25 @@ fun AppRoot() { } Box(modifier = Modifier.fillMaxSize()) { - MainScaffold( + // 背景图片 - 填充整个屏幕包括系统栏,使用FillBounds确保完全填充 + Image( + painter = painterResource(id = R.drawable.background), + contentDescription = null, + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.FillBounds, + alpha = 0.8f + ) + + // 半透明遮罩层 - 填充整个屏幕包括系统栏 + Box( + modifier = Modifier + .fillMaxSize() + .background(Color(0x88121212)) + ) + + // 主内容 - 添加系统栏内边距 + Box(modifier = Modifier.fillMaxSize().systemBarsPadding()) { + MainScaffold( selectedRoom = selectedRoom, onRoomSelect = { selectedRoom = it }, selectedNavItem = selectedNavItem, @@ -96,6 +150,7 @@ fun AppRoot() { } } ) + } } } diff --git a/app/src/main/java/com/example/smarthome/ui/MainScaffold.kt b/app/src/main/java/com/example/smarthome/ui/MainScaffold.kt index ef209e4..2cc27b9 100644 --- a/app/src/main/java/com/example/smarthome/ui/MainScaffold.kt +++ b/app/src/main/java/com/example/smarthome/ui/MainScaffold.kt @@ -77,7 +77,7 @@ fun MainScaffold( onAddRoom: (String) -> Unit = {}, onDeleteRoom: (Int) -> Unit = {} ) { - Row(modifier = Modifier.fillMaxSize().background(Color(0xFF121212))) { + Row(modifier = Modifier.fillMaxSize()) { SideNavRail( selectedNavItem = selectedNavItem, onNavItemSelect = onNavItemSelect @@ -125,13 +125,8 @@ fun DashboardContent( editMode = editMode, onEditModeChange = { editMode = it } ) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(16.dp)) { - AirConditionerCard(modifier = Modifier.weight(1f)) - UsageStatusChart(modifier = Modifier.weight(1f)) - } - LightRow(modifier = Modifier.fillMaxWidth().padding(bottom = 16.dp)) - ModeButtonsRow(onModeSelected = { }) - MyDevicesGrid(selectedRoom = selectedRoom, modifier = Modifier.fillMaxSize()) + // 根据选中的房间显示不同的内容 + RoomContent(selectedRoom = selectedRoom, roomName = rooms.getOrNull(selectedRoom) ?: "总览") } if (showAddRoomDialog) { @@ -146,6 +141,77 @@ fun DashboardContent( } } +@Composable +fun RoomContent(selectedRoom: Int, roomName: String) { + // 根据房间索引显示不同的内容 + when (selectedRoom) { + 0 -> OverviewRoomContent() // 总览 + else -> SpecificRoomContent(selectedRoom, roomName) // 具体房间 + } +} + +@Composable +fun OverviewRoomContent() { + Column(modifier = Modifier.fillMaxSize()) { + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(16.dp)) { + AirConditionerCard(modifier = Modifier.weight(1f), roomName = "全屋") + UsageStatusChart(modifier = Modifier.weight(1f), roomName = "全屋") + } + LightRow(modifier = Modifier.fillMaxWidth().padding(bottom = 16.dp), roomName = "全屋") + ModeButtonsRow(onModeSelected = { }) + + // 显示所有房间的设备摘要 + Text( + text = "所有设备", + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + color = Color.White, + modifier = Modifier.padding(vertical = 12.dp) + ) + AllDevicesOverview(modifier = Modifier.fillMaxSize()) + } +} + +@Composable +fun SpecificRoomContent(selectedRoom: Int, roomName: String) { + Column(modifier = Modifier.fillMaxSize()) { + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(16.dp)) { + AirConditionerCard(modifier = Modifier.weight(1f), roomName = roomName) + UsageStatusChart(modifier = Modifier.weight(1f), roomName = roomName) + } + LightRow(modifier = Modifier.fillMaxWidth().padding(bottom = 16.dp), roomName = roomName) + + Text( + text = "$roomName 设备", + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + color = Color.White, + modifier = Modifier.padding(vertical = 12.dp) + ) + MyDevicesGrid(selectedRoom = selectedRoom, modifier = Modifier.fillMaxSize()) + } +} + +@Composable +fun AllDevicesOverview(modifier: Modifier = Modifier) { + val allDevices = listOf( + Device("客厅空调", "24°C", R.drawable.ic_ac, true), + Device("客厅灯光", "80%", R.drawable.ic_light, true), + Device("厨房灯光", "60%", R.drawable.ic_light, true), + Device("卧室空调", "22°C", R.drawable.ic_ac, false), + Device("影音室电视", "运行中", R.drawable.ic_media, true), + Device("游戏房主机", "待机中", R.drawable.ic_media, false) + ) + LazyVerticalGrid( + columns = GridCells.Adaptive(minSize = 140.dp), + modifier = modifier, + horizontalArrangement = Arrangement.spacedBy(12.dp), + verticalArrangement = Arrangement.spacedBy(12.dp) + ) { + items(allDevices) { d -> DeviceCard(d) } + } +} + @Composable fun HeaderHero() { TopBar() @@ -430,7 +496,7 @@ fun NavItem(title: String, selected: Boolean) { @Composable fun SideNavRail(selectedNavItem: Int = 0, onNavItemSelect: (Int) -> Unit = {}) { Column(modifier = Modifier.width(120.dp).fillMaxHeight().padding(12.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) { - Box(modifier = Modifier.size(48.dp).clip(RoundedCornerShape(16.dp)).background(Color(0x22121212))) + Spacer(modifier = Modifier.height(48.dp)) NavRailItem("控制台", R.drawable.ic_dashboard, selectedNavItem == 0, onClick = { onNavItemSelect(0) }) NavRailItem("最近", R.drawable.ic_recent, selectedNavItem == 1, onClick = { onNavItemSelect(1) }) NavRailItem("收藏", R.drawable.ic_bookmark, selectedNavItem == 2, onClick = { onNavItemSelect(2) }) @@ -499,14 +565,11 @@ fun NavRailItem(text: String, iconRes: Int, selected: Boolean, onClick: () -> Un @Composable fun TopBar() { Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) { - Text(text = "控制台", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold) + Text(text = "控制台", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = Color.White) Row(horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically) { Box(modifier = Modifier.width(280.dp).height(40.dp).clip(RoundedCornerShape(20.dp)).background(Color(0x22121212)).padding(horizontal = 16.dp), contentAlignment = Alignment.CenterStart) { Text(text = "搜索关键词", color = Color(0xFF9AA0A6)) } - Box(modifier = Modifier.size(40.dp).clip(RoundedCornerShape(12.dp)).background(Color(0x22121212))) - Box(modifier = Modifier.size(40.dp).clip(RoundedCornerShape(12.dp)).background(Color(0x22121212))) - Box(modifier = Modifier.size(40.dp).clip(RoundedCornerShape(12.dp)).background(Color(0x22121212))) GradientButton("+ 添加设备") } } @@ -522,30 +585,78 @@ fun GradientButton(text: String, onClick: () -> Unit = {}) { @Composable fun MyDevicesGrid(selectedRoom: Int, modifier: Modifier = Modifier) { val devices = when (selectedRoom) { - 1 -> listOf( - Device("智能电视", "已运行 3 小时", R.drawable.ic_media, true), - Device("音响", "已运行 3 小时", R.drawable.ic_media, false), - Device("路由器", "已运行 3 小时", R.drawable.ic_security, true), - Device("无线网络", "已运行 3 小时", R.drawable.ic_security, true), - Device("暖气", "已运行 3 小时", R.drawable.ic_media, false), - Device("插座", "已运行 3 小时", R.drawable.ic_media, true) + 1 -> listOf( // 客厅 + Device("智能电视", "运行中", R.drawable.ic_media, true), + Device("音响", "待机中", R.drawable.ic_media, false), + Device("空调", "24°C", R.drawable.ic_ac, true), + Device("主灯", "80%", R.drawable.ic_light, true), + Device("窗帘", "已打开", R.drawable.ic_curtain, true), + Device("插座", "运行中", R.drawable.ic_light, true) + ) + 2 -> listOf( // 厨房 + Device("冰箱", "运行中", R.drawable.ic_ac, true), + Device("微波炉", "待机中", R.drawable.ic_media, false), + Device("油烟机", "待机中", R.drawable.ic_media, false), + Device("灯光", "60%", R.drawable.ic_light, true) + ) + 3 -> listOf( // 卧室 + Device("空调", "22°C", R.drawable.ic_ac, true), + Device("床头灯", "40%", R.drawable.ic_light, true), + Device("窗帘", "已关闭", R.drawable.ic_curtain, false), + Device("加湿器", "运行中", R.drawable.ic_media, true), + Device("空气净化器", "运行中", R.drawable.ic_security, true) + ) + 4 -> listOf( // 影音室 + Device("投影仪", "运行中", R.drawable.ic_media, true), + Device("功放", "运行中", R.drawable.ic_media, true), + Device("音响系统", "运行中", R.drawable.ic_media, true), + Device("灯光", "20%", R.drawable.ic_light, true), + Device("窗帘", "已关闭", R.drawable.ic_curtain, false), + Device("空调", "23°C", R.drawable.ic_ac, true) + ) + 5 -> listOf( // 游戏房 + Device("游戏主机", "运行中", R.drawable.ic_media, true), + Device("显示器", "运行中", R.drawable.ic_media, true), + Device("RGB灯带", "运行中", R.drawable.ic_light, true), + Device("空调", "20°C", R.drawable.ic_ac, true), + Device("路由器", "运行中", R.drawable.ic_security, true) ) else -> emptyList() } - LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 140.dp), modifier = modifier.fillMaxSize(), horizontalArrangement = Arrangement.spacedBy(12.dp), verticalArrangement = Arrangement.spacedBy(12.dp)) { + LazyVerticalGrid( + columns = GridCells.Adaptive(minSize = 140.dp), + modifier = modifier, + horizontalArrangement = Arrangement.spacedBy(12.dp), + verticalArrangement = Arrangement.spacedBy(12.dp) + ) { items(devices) { d -> DeviceCard(d) } } } @Composable -fun UsageStatusChart(modifier: Modifier = Modifier) { - val values = listOf(12f, 18f, 16f, 30f, 20f, 22f, 17f, 19f, 25f, 32f) +fun UsageStatusChart(modifier: Modifier = Modifier, roomName: String = "房间") { + // 根据房间生成不同的数据 + val values = remember(roomName) { + List(10) { (10..35).random().toFloat() } + } + val totalPower = remember(roomName) { (15.0 + Math.random() * 30).toString().take(5) } + val totalHours = remember(roomName) { (10 + (Math.random() * 40).toInt()) } + Box(modifier = modifier.height(220.dp).clip(RoundedCornerShape(24.dp)).background(Color(0x26121212)).padding(16.dp)) { Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { - Text(text = "使用状态", fontWeight = FontWeight.SemiBold) + Column { + Text(text = "使用状态", fontWeight = FontWeight.SemiBold, color = Color.White) + Text(text = roomName, fontSize = 12.sp, color = Color(0xFF9AA0A6)) + } Row(horizontalArrangement = Arrangement.spacedBy(24.dp)) { - Column { Text(text = "35.02kWh"); Text(text = "总消耗", color = Color(0xFF9AA0A6)) } - Column { Text(text = "32h"); Text(text = "总时长", color = Color(0xFF9AA0A6)) } + Column { + Text(text = "${totalPower}kWh", color = Color.White) + Text(text = "总消耗", color = Color(0xFF9AA0A6), fontSize = 12.sp) + } + Column { + Text(text = "${totalHours}h", color = Color.White) + Text(text = "总时长", color = Color(0xFF9AA0A6), fontSize = 12.sp) + } } Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.Bottom) { values.forEach { v -> @@ -557,16 +668,26 @@ fun UsageStatusChart(modifier: Modifier = Modifier) { } @Composable -fun AirConditionerCard(modifier: Modifier = Modifier) { +fun AirConditionerCard(modifier: Modifier = Modifier, roomName: String = "房间") { var temp by remember { mutableStateOf(24f) } + var isOn by remember { mutableStateOf(true) } + Box(modifier = modifier.height(220.dp).clip(RoundedCornerShape(24.dp)).background(Color(0x26121212)).padding(16.dp)) { Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { Row(horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) { - Text(text = "空调", fontWeight = FontWeight.SemiBold) - Switch(checked = true, onCheckedChange = {}) + Column { + Text(text = "空调", fontWeight = FontWeight.SemiBold, color = Color.White) + Text(text = roomName, fontSize = 12.sp, color = Color(0xFF9AA0A6)) + } + Switch(checked = isOn, onCheckedChange = { isOn = it }) } - Text(text = "24°C", style = MaterialTheme.typography.headlineMedium) - Slider(value = temp, onValueChange = { temp = it }, valueRange = 16f..32f) + Text(text = "${temp.toInt()}°C", style = MaterialTheme.typography.headlineMedium, color = Color.White) + Slider( + value = temp, + onValueChange = { temp = it }, + valueRange = 16f..32f, + enabled = isOn + ) Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) { Box(modifier = Modifier.size(36.dp).clip(RoundedCornerShape(10.dp)).background(Color(0x22121212))) Box(modifier = Modifier.size(36.dp).clip(RoundedCornerShape(10.dp)).background(Color(0x22121212))) @@ -765,14 +886,14 @@ fun ModeButton( } @Composable -fun LightRow(modifier: Modifier = Modifier) { - val lights = listOf( - "灯光 1" to 0.6f, - "灯光 2" to 0.8f, - "灯光 3" to 0.45f, - "灯光 4" to 0.6f, - "灯光 5" to 0.6f - ).take(2) +fun LightRow(modifier: Modifier = Modifier, roomName: String = "房间") { + // 根据房间生成不同的灯光数据 + val lights = remember(roomName) { + listOf( + "$roomName 主灯" to (0.5f + Math.random().toFloat() * 0.4f), + "$roomName 辅灯" to (0.5f + Math.random().toFloat() * 0.4f) + ) + } Row(modifier = modifier, horizontalArrangement = Arrangement.spacedBy(16.dp)) { lights.forEach { (name, percent) -> LightCard(name = name, percent = percent, modifier = Modifier.weight(1f)) diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 624d3b2..016cbb6 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -3,8 +3,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@drawable/bg_radial_overlay" - android:fitsSystemWindows="true"> + android:background="@android:color/transparent" + android:fitsSystemWindows="false">