优化界面

This commit is contained in:
zzh 2026-02-24 13:44:25 +08:00
parent bde499ba15
commit 8051ff242a
13 changed files with 2087 additions and 1228 deletions

View File

@ -1,16 +1,17 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.plugin.compose")
}
android {
namespace = "com.example.smarthome"
compileSdk = 35
compileSdk = 36
defaultConfig {
applicationId = "com.example.smarthome"
minSdk = 24
targetSdk = 35
minSdk = 33 // Android 13+
targetSdk = 36
versionCode = 1
versionName = "1.0"
vectorDrawables {
@ -36,9 +37,6 @@ android {
compose = true
viewBinding = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.14"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
@ -67,7 +65,9 @@ dependencies {
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.material3:material3-window-size-class:1.3.0")
implementation("com.github.Dimezis:BlurView:version-3.2.0")
// Haze - 现代毛玻璃效果库
implementation("dev.chrisbanes.haze:haze:1.7.1")
implementation("com.google.code.gson:gson:2.10.1")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.google.android.gms:play-services-location:21.0.1")

View File

@ -16,5 +16,8 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivityHaze" />
<activity android:name=".MainActivityCompose" />
<activity android:name=".MainActivityAlternative" />
</application>
</manifest>

View File

@ -7,8 +7,6 @@ import com.example.smarthome.ui.theme.SmartHomeTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.ViewCompositionStrategy
import eightbitlab.com.blurview.BlurTarget
import eightbitlab.com.blurview.BlurView
import androidx.compose.material3.Surface
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
@ -31,6 +29,7 @@ import androidx.compose.runtime.collectAsState
import com.example.smarthome.data.BackgroundManager
import com.example.smarthome.data.LanguageManager
import com.example.smarthome.data.UserManager
import com.example.smarthome.ui.SmartHomeScreen
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@ -53,14 +52,6 @@ class MainActivity : ComponentActivity() {
}
}
val decorView = window.decorView
val blurTarget = findViewById<BlurTarget>(R.id.blurTarget)
val blurView = findViewById<BlurView>(R.id.blurView)
val windowBackground: Drawable? = decorView.background
blurView.setupWith(blurTarget)
.setFrameClearDrawable(windowBackground)
.setBlurRadius(20f)
}
private fun hideStatusBar() {
// 设置全屏模式,让内容延伸到系统栏区域
@ -174,7 +165,10 @@ fun MainContent() {
Box(modifier = Modifier.fillMaxSize()) {
MainScaffold(
selectedRoom = selectedRoom,
onRoomSelect = { selectedRoom = it },
onRoomSelect = { roomIndex ->
selectedRoom = roomIndex
selectedNavItem = 0 // 切换到控制台页面
},
selectedNavItem = selectedNavItem,
onNavItemSelect = { selectedNavItem = it },
rooms = rooms,

View File

@ -0,0 +1,12 @@
package com.example.smarthome
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class MainActivityAlternative : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 简单的空 Activity
}
}

View File

@ -0,0 +1,176 @@
package com.example.smarthome
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.blur
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.smarthome.ui.theme.SmartHomeTheme
class MainActivityCompose : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
SmartHomeTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = Color(0xFF1A1A2E)
) {
SmartHomeScreen()
}
}
}
}
}
@Composable
fun SmartHomeScreen() {
Box(
modifier = Modifier
.fillMaxSize()
.background(
Brush.verticalGradient(
colors = listOf(
Color(0xFF1A1A2E),
Color(0xFF16213E),
Color(0xFF0F3460)
)
)
)
) {
Row(
modifier = Modifier.fillMaxSize()
) {
// 左侧毛玻璃边栏
GlassSidebar(
modifier = Modifier
.width(260.dp)
.padding(24.dp)
)
// 主内容区域
Box(
modifier = Modifier
.fillMaxSize()
.padding(24.dp),
contentAlignment = Alignment.Center
) {
GlassCard()
}
}
}
}
@Composable
fun GlassSidebar(
modifier: Modifier = Modifier
) {
Box(
modifier = modifier
.fillMaxHeight()
.clip(RoundedCornerShape(32.dp))
.background(
Brush.linearGradient(
colors = listOf(
Color.White.copy(alpha = 0.15f),
Color.White.copy(alpha = 0.08f)
)
)
)
.blur(20.dp)
.padding(32.dp)
) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Text(
text = "Lumina",
color = Color.White,
fontSize = 32.sp,
fontWeight = FontWeight.Bold
)
Text(
text = "Smart Home",
color = Color.White.copy(alpha = 0.6f),
fontSize = 14.sp
)
Spacer(modifier = Modifier.height(32.dp))
listOf("🏠 首页", "🌡️ 温控", "💡 照明", "🔒 安全").forEach { item ->
Text(
text = item,
color = if (item == "🏠 首页") Color.White else Color.White.copy(alpha = 0.6f),
fontSize = 16.sp,
modifier = Modifier.padding(vertical = 8.dp)
)
}
}
}
}
@Composable
fun GlassCard() {
Box(
modifier = Modifier
.width(400.dp)
.height(250.dp)
.clip(RoundedCornerShape(24.dp))
.background(
Brush.linearGradient(
colors = listOf(
Color.White.copy(alpha = 0.20f),
Color.White.copy(alpha = 0.12f),
Color.White.copy(alpha = 0.06f)
)
)
)
.blur(25.dp)
.padding(32.dp),
contentAlignment = Alignment.CenterStart
) {
Column(
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(
text = "智能家居控制中心",
color = Color.White,
fontSize = 24.sp,
fontWeight = FontWeight.Bold
)
Text(
text = "当前温度: 26°C",
color = Color.White.copy(alpha = 0.8f),
fontSize = 16.sp
)
Text(
text = "湿度: 65%",
color = Color.White.copy(alpha = 0.8f),
fontSize = 16.sp
)
Text(
text = "空气质量: 优",
color = Color.White.copy(alpha = 0.8f),
fontSize = 16.sp
)
}
}
}

View File

@ -0,0 +1,215 @@
package com.example.smarthome
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import dev.chrisbanes.haze.HazeState
import dev.chrisbanes.haze.HazeStyle
import dev.chrisbanes.haze.HazeTint
import dev.chrisbanes.haze.haze
import dev.chrisbanes.haze.hazeChild
import dev.chrisbanes.haze.hazeEffect
import dev.chrisbanes.haze.hazeSource
import com.example.smarthome.ui.theme.SmartHomeTheme
import androidx.compose.ui.platform.LocalDensity
class MainActivityHaze : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
SmartHomeTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = Color(0xFF1A1A2E)
) {
SmartHomeScreenWithHaze()
}
}
}
}
}
@Composable
fun SmartHomeScreenWithHaze() {
val hazeState = HazeState()
val density = LocalDensity.current
Box(
modifier = Modifier
.fillMaxSize()
.background(
Brush.verticalGradient(
colors = listOf(
Color(0xFF1A1A2E),
Color(0xFF16213E),
Color(0xFF0F3460)
)
)
)
.hazeSource(state = hazeState)
) {
// 背景装饰内容
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally
) {
repeat(5) { index ->
with(density) {
val sizeDp = (100 + index * 20).dp
Box(
modifier = Modifier
.size(sizeDp)
.clip(RoundedCornerShape(50))
.background(
Brush.radialGradient(
colors = listOf(
Color(0xFF6C5CE7),
Color(0xFFA29BFE),
Color.Transparent
)
)
)
)
}
}
}
Row(
modifier = Modifier.fillMaxSize()
) {
// 左侧毛玻璃边栏
HazeSidebar(
modifier = Modifier
.width(260.dp)
.padding(24.dp),
hazeState = hazeState
)
// 主内容区域
Box(
modifier = Modifier
.fillMaxSize()
.padding(24.dp),
contentAlignment = Alignment.Center
) {
HazeCard(hazeState = hazeState)
}
}
}
}
@Composable
fun HazeSidebar(
modifier: Modifier = Modifier,
hazeState: HazeState
) {
Box(
modifier = modifier
.fillMaxHeight()
.clip(RoundedCornerShape(32.dp))
.hazeEffect(
state = hazeState,
style = HazeStyle(
blurRadius = 20.dp,
tint = HazeTint(Color.White.copy(alpha = 0.15f)),
noiseFactor = 0.0f
)
)
.padding(32.dp)
) {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Text(
text = "Lumina",
color = Color.White,
fontSize = 32.sp,
fontWeight = FontWeight.Bold
)
Text(
text = "Smart Home",
color = Color.White.copy(alpha = 0.6f),
fontSize = 14.sp
)
Spacer(modifier = Modifier.height(32.dp))
listOf("🏠 首页", "🌡️ 温控", "💡 照明", "🔒 安全").forEach { item ->
Text(
text = item,
color = if (item == "🏠 首页") Color.White else Color.White.copy(alpha = 0.6f),
fontSize = 16.sp,
modifier = Modifier.padding(vertical = 8.dp)
)
}
}
}
}
@Composable
fun HazeCard(
hazeState: HazeState
) {
Box(
modifier = Modifier
.width(400.dp)
.height(250.dp)
.clip(RoundedCornerShape(24.dp))
.hazeEffect(
state = hazeState,
style = HazeStyle(
blurRadius = 25.dp,
tint = HazeTint(Color.White.copy(alpha = 0.2f)),
noiseFactor = 0.0f
)
)
.padding(32.dp),
contentAlignment = Alignment.CenterStart
) {
Column(
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(
text = "智能家居控制中心",
color = Color.White,
fontSize = 24.sp,
fontWeight = FontWeight.Bold
)
Text(
text = "当前温度: 26°C",
color = Color.White.copy(alpha = 0.8f),
fontSize = 16.sp
)
Text(
text = "湿度: 65%",
color = Color.White.copy(alpha = 0.8f),
fontSize = 16.sp
)
Text(
text = "空气质量: 优",
color = Color.White.copy(alpha = 0.8f),
fontSize = 16.sp
)
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,613 @@
package com.example.smarthome.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.smarthome.R
import com.example.smarthome.data.tr
@Composable
fun EditRoomsDialog(
rooms: List<String>,
onDismiss: () -> Unit,
onRenameRoom: (Int, String) -> Unit,
onDeleteRoom: (Int) -> Unit,
onAddRoom: () -> Unit = {}
) {
// 当前编辑的房间索引
var editingIndex by remember { mutableStateOf(-1) }
var editingName by remember { mutableStateOf("") }
// 背景遮罩
Box(
modifier = Modifier
.fillMaxSize()
.clickable(
indication = null,
interactionSource = remember { androidx.compose.foundation.interaction.MutableInteractionSource() }
) { onDismiss() },
contentAlignment = Alignment.TopCenter
) {
// 对话框主体 - 往上挪,使用透明卡片风格
Box(
modifier = Modifier
.padding(top = 60.dp, bottom = 60.dp)
.widthIn(max = 420.dp)
.fillMaxWidth(0.9f)
.clip(RoundedCornerShape(28.dp))
.background(Color(0xFF1A1A1A).copy(alpha = 0.65f))
.border(
width = 1.dp,
color = Color.White.copy(alpha = 0.15f),
shape = RoundedCornerShape(28.dp)
)
.clickable(
indication = null,
interactionSource = remember { androidx.compose.foundation.interaction.MutableInteractionSource() }
) { /* 阻止点击穿透 */ }
.padding(28.dp)
) {
Column(
verticalArrangement = Arrangement.spacedBy(20.dp)
) {
// 标题区域
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
Box(
modifier = Modifier
.size(44.dp)
.clip(RoundedCornerShape(12.dp))
.background(
Brush.linearGradient(
listOf(Color(0xFF00D1FF).copy(alpha = 0.3f), Color(0xFFB89CFF).copy(alpha = 0.3f))
)
),
contentAlignment = Alignment.Center
) {
Text(text = "🏠", fontSize = 22.sp)
}
Column {
Text(
text = "编辑房间",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = Color.White
)
Text(
text = "管理你的房间列表",
fontSize = 12.sp,
color = Color(0xFF9AA0A6)
)
}
}
Box(
modifier = Modifier
.size(32.dp)
.clip(RoundedCornerShape(8.dp))
.background(Color(0x33FFFFFF))
.clickable { onDismiss() },
contentAlignment = Alignment.Center
) {
Text(text = "", color = Color(0xFF9AA0A6), fontSize = 14.sp)
}
}
// 房间列表 - 使用 weight 占据剩余空间,确保底部按钮始终可见
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.weight(1f, fill = false)
.verticalScroll(rememberScrollState())
) {
rooms.forEachIndexed { index, name ->
Row(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(14.dp))
.background(Color.White.copy(alpha = 0.1f))
.padding(12.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
if (editingIndex == index) {
// 编辑模式 - 使用 BasicTextField 去掉内层框
BasicTextField(
value = editingName,
onValueChange = { editingName = it },
modifier = Modifier
.weight(1f)
.padding(end = 12.dp),
textStyle = androidx.compose.ui.text.TextStyle(
fontSize = 15.sp,
color = Color.White
),
singleLine = true,
cursorBrush = SolidColor(Color(0xFF00D1FF))
)
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
// 确认按钮
Box(
modifier = Modifier
.size(32.dp)
.clip(RoundedCornerShape(8.dp))
.background(Color(0xFF00D1FF).copy(alpha = 0.2f))
.clickable(enabled = editingName.isNotBlank()) {
if (editingName.isNotBlank()) {
onRenameRoom(index, editingName.trim())
editingIndex = -1
editingName = ""
}
},
contentAlignment = Alignment.Center
) {
Text(
text = "",
color = if (editingName.isNotBlank()) Color(0xFF00D1FF) else Color(0xFF6A6A7A),
fontSize = 16.sp
)
}
// 取消按钮
Box(
modifier = Modifier
.size(32.dp)
.clip(RoundedCornerShape(8.dp))
.background(Color(0xFF3A3A4E))
.clickable {
editingIndex = -1
editingName = ""
},
contentAlignment = Alignment.Center
) {
Text(
text = "",
color = Color(0xFF9AA0A6),
fontSize = 14.sp
)
}
}
} else {
// 显示模式
Text(
text = name,
color = Color.White,
fontSize = 15.sp,
modifier = Modifier.weight(1f)
)
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
// 编辑按钮
Box(
modifier = Modifier
.size(32.dp)
.clip(RoundedCornerShape(8.dp))
.background(Color(0xFF00D1FF).copy(alpha = 0.2f))
.clickable {
editingIndex = index
editingName = name
},
contentAlignment = Alignment.Center
) {
Text(
text = "✏️",
color = Color(0xFF00D1FF),
fontSize = 14.sp
)
}
// 删除按钮(总览不能删除)
if (index != 0) {
Box(
modifier = Modifier
.size(32.dp)
.clip(RoundedCornerShape(8.dp))
.background(Color(0xFFFF5252).copy(alpha = 0.2f))
.clickable { onDeleteRoom(index) },
contentAlignment = Alignment.Center
) {
Text(
text = "🗑️",
color = Color(0xFFFF5252),
fontSize = 14.sp
)
}
}
}
}
}
}
}
// 添加新房间按钮
Box(
modifier = Modifier
.fillMaxWidth()
.height(52.dp)
.clip(RoundedCornerShape(14.dp))
.background(Color(0xFF1A1A2E))
.border(
width = 1.dp,
color = Color(0xFF3A3A4E),
shape = RoundedCornerShape(14.dp)
)
.clickable { onAddRoom() },
contentAlignment = Alignment.Center
) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "+",
color = Color.White,
fontWeight = FontWeight.Bold,
fontSize = 18.sp
)
Text(
text = "添加房间",
color = Color.White,
fontWeight = FontWeight.Medium,
fontSize = 15.sp
)
}
}
// 完成按钮
Box(
modifier = Modifier
.fillMaxWidth()
.height(52.dp)
.clip(RoundedCornerShape(14.dp))
.background(
Brush.linearGradient(listOf(Color(0xFF00D1FF), Color(0xFFB89CFF)))
)
.clickable { onDismiss() },
contentAlignment = Alignment.Center
) {
Text(
text = "完成",
color = Color.White,
fontWeight = FontWeight.Bold,
fontSize = 15.sp
)
}
}
}
}
}
@Composable
fun AddRoomDialog(
onDismiss: () -> Unit,
onConfirm: (String) -> Unit
) {
var roomName by remember { mutableStateOf("") }
var selectedIcon by remember { mutableStateOf(0) }
// 房间建议
val roomSuggestions = listOf("书房", "餐厅", "阳台", "卫生间", "储物间", "健身房", "茶室", "儿童房")
// 房间图标
val roomIcons = listOf("🏠", "🛋️", "🍳", "🛏️", "🎬", "🎮", "📚", "🍽️", "🌿", "🏋️", "🍵", "🧸")
// 背景遮罩(点击关闭)
Box(
modifier = Modifier
.fillMaxSize()
.clickable(
indication = null,
interactionSource = remember { androidx.compose.foundation.interaction.MutableInteractionSource() }
) { onDismiss() },
contentAlignment = Alignment.Center
) {
// 对话框主体
Box(
modifier = Modifier
.width(400.dp)
.clip(RoundedCornerShape(28.dp))
.background(
Brush.verticalGradient(
listOf(
Color(0xFF2A2A3E),
Color(0xFF1A1A2E)
)
)
)
.border(
width = 1.dp,
brush = Brush.linearGradient(
listOf(Color(0xFF00D1FF).copy(alpha = 0.3f), Color(0xFFB89CFF).copy(alpha = 0.3f))
),
shape = RoundedCornerShape(28.dp)
)
.clickable(
indication = null,
interactionSource = remember { androidx.compose.foundation.interaction.MutableInteractionSource() }
) { /* 阻止点击穿透 */ }
.padding(28.dp)
) {
Column(
verticalArrangement = Arrangement.spacedBy(24.dp)
) {
// 标题区域
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
Box(
modifier = Modifier
.size(44.dp)
.clip(RoundedCornerShape(12.dp))
.background(
Brush.linearGradient(
listOf(Color(0xFF00D1FF).copy(alpha = 0.3f), Color(0xFFB89CFF).copy(alpha = 0.3f))
)
),
contentAlignment = Alignment.Center
) {
Text(text = "", fontSize = 22.sp)
}
Column {
Text(
text = "添加房间",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = Color.White
)
Text(
text = "创建一个新的房间",
fontSize = 12.sp,
color = Color(0xFF9AA0A6)
)
}
}
Box(
modifier = Modifier
.size(32.dp)
.clip(RoundedCornerShape(8.dp))
.background(Color(0x33FFFFFF))
.clickable { onDismiss() },
contentAlignment = Alignment.Center
) {
Text(text = "", color = Color(0xFF9AA0A6), fontSize = 14.sp)
}
}
// 房间名称输入
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
Text(
text = "房间名称",
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
color = Color(0xFFB0B0B0)
)
TextField(
value = roomName,
onValueChange = { roomName = it },
placeholder = { Text("输入房间名称...", color = Color(0xFF6A6A7A)) },
modifier = Modifier
.fillMaxWidth()
.height(56.dp),
colors = TextFieldDefaults.colors(
focusedContainerColor = Color(0xFF1A1A2E),
unfocusedContainerColor = Color(0xFF1A1A2E),
focusedTextColor = Color.White,
unfocusedTextColor = Color.White,
cursorColor = Color(0xFF00D1FF),
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(14.dp),
singleLine = true,
textStyle = androidx.compose.ui.text.TextStyle(fontSize = 16.sp)
)
}
// 快速选择
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
Text(
text = "快速选择",
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
color = Color(0xFFB0B0B0)
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
roomSuggestions.take(3).forEach { suggestion ->
Box(
modifier = Modifier
.clip(RoundedCornerShape(20.dp))
.background(
if (roomName == suggestion) Color(0xFF00D1FF).copy(alpha = 0.3f)
else Color(0xFF1A1A2E)
)
.border(
width = 1.dp,
color = if (roomName == suggestion) Color(0xFF00D1FF) else Color(0xFF3A3A4E),
shape = RoundedCornerShape(20.dp)
)
.clickable { roomName = suggestion }
.padding(horizontal = 16.dp, vertical = 8.dp)
) {
Text(
text = suggestion,
color = if (roomName == suggestion) Color.White else Color(0xFF9AA0A6),
fontSize = 13.sp
)
}
}
}
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
roomSuggestions.drop(3).forEach { suggestion ->
Box(
modifier = Modifier
.clip(RoundedCornerShape(20.dp))
.background(
if (roomName == suggestion) Color(0xFF00D1FF).copy(alpha = 0.3f)
else Color(0xFF1A1A2E)
)
.border(
width = 1.dp,
color = if (roomName == suggestion) Color(0xFF00D1FF) else Color(0xFF3A3A4E),
shape = RoundedCornerShape(20.dp)
)
.clickable { roomName = suggestion }
.padding(horizontal = 16.dp, vertical = 8.dp)
) {
Text(
text = suggestion,
color = if (roomName == suggestion) Color.White else Color(0xFF9AA0A6),
fontSize = 13.sp
)
}
}
}
}
// 选择图标
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
Text(
text = "选择图标",
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
color = Color(0xFFB0B0B0)
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
roomIcons.forEachIndexed { index, icon ->
Box(
modifier = Modifier
.size(44.dp)
.clip(RoundedCornerShape(12.dp))
.then(
if (selectedIcon == index)
Modifier.background(Brush.linearGradient(listOf(Color(0xFF00D1FF), Color(0xFFB89CFF))))
else Modifier.background(Color(0xFF1A1A2E))
)
.border(
width = if (selectedIcon == index) 0.dp else 1.dp,
color = Color(0xFF3A3A4E),
shape = RoundedCornerShape(12.dp)
)
.clickable { selectedIcon = index },
contentAlignment = Alignment.Center
) {
Text(text = icon, fontSize = 20.sp)
}
}
}
}
// 按钮区域
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
// 取消按钮
Box(
modifier = Modifier
.weight(1f)
.height(52.dp)
.clip(RoundedCornerShape(14.dp))
.background(Color(0xFF1A1A2E))
.border(
width = 1.dp,
color = Color(0xFF3A3A4E),
shape = RoundedCornerShape(14.dp)
)
.clickable { onDismiss() },
contentAlignment = Alignment.Center
) {
Text(
text = "取消",
color = Color(0xFFB0B0B0),
fontWeight = FontWeight.Medium,
fontSize = 15.sp
)
}
// 确定按钮
Box(
modifier = Modifier
.weight(1f)
.height(52.dp)
.clip(RoundedCornerShape(14.dp))
.background(
if (roomName.isNotBlank())
Brush.linearGradient(listOf(Color(0xFF00D1FF), Color(0xFFB89CFF)))
else
Brush.linearGradient(listOf(Color(0xFF3A3A4E), Color(0xFF3A3A4E)))
)
.clickable(enabled = roomName.isNotBlank()) {
if (roomName.isNotBlank()) {
onConfirm(roomName.trim())
}
},
contentAlignment = Alignment.Center
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
text = "",
color = if (roomName.isNotBlank()) Color.White else Color(0xFF6A6A7A),
fontSize = 16.sp
)
Text(
text = "添加房间",
color = if (roomName.isNotBlank()) Color.White else Color(0xFF6A6A7A),
fontWeight = FontWeight.Bold,
fontSize = 15.sp
)
}
}
}
}
}
}
}

View File

@ -46,7 +46,13 @@ fun SettingsScreen(onBack: () -> Unit) {
}
@Composable
fun SettingsContentList() {
fun SettingsContentList(
rooms: List<String> = listOf("总览", "客厅", "厨房", "卧室", "影音室", "游戏房"),
onAddRoom: (String) -> Unit = {},
onDeleteRoom: (Int) -> Unit = {},
onRenameRoom: (Int, String) -> Unit = { _, _ -> },
onShowEditRoomsDialog: () -> Unit = {}
) {
val context = LocalContext.current
val currentLang by LanguageManager.currentLanguage.collectAsState()
var showLanguageDialog by remember { mutableStateOf(false) }
@ -81,6 +87,12 @@ fun SettingsContentList() {
}}
item { SettingsSection(title = tr("settings_device")) {
SettingsItem(
title = "房间管理",
subtitle = "添加、删除或重命名房间",
onClick = { onShowEditRoomsDialog() }
)
var autoConnect by remember { mutableStateOf(true) }
SettingsSwitchItem(
title = tr("settings_auto_connect"),
@ -466,7 +478,14 @@ fun LogoutButton(onClick: () -> Unit) {
@Composable
fun SettingsContent() {
fun SettingsContent(
rooms: List<String> = listOf("总览", "客厅", "厨房", "卧室", "影音室", "游戏房"),
onAddRoom: (String) -> Unit = {},
onDeleteRoom: (Int) -> Unit = {},
onRenameRoom: (Int, String) -> Unit = { _, _ -> }
) {
var showEditRoomsDialog by remember { mutableStateOf(false) }
Column(
modifier = Modifier
.fillMaxSize()
@ -482,7 +501,24 @@ fun SettingsContent() {
)
// 设置内容
SettingsContentList()
SettingsContentList(
rooms = rooms,
onAddRoom = onAddRoom,
onDeleteRoom = onDeleteRoom,
onRenameRoom = onRenameRoom,
onShowEditRoomsDialog = { showEditRoomsDialog = true }
)
}
// 编辑房间对话框
if (showEditRoomsDialog) {
EditRoomsDialog(
rooms = rooms,
onDismiss = { showEditRoomsDialog = false },
onRenameRoom = onRenameRoom,
onDeleteRoom = onDeleteRoom,
onAddRoom = { /* 添加房间通过对话框内的按钮处理 */ }
)
}
}

View File

@ -0,0 +1,345 @@
package com.example.smarthome.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import dev.chrisbanes.haze.HazeState
import dev.chrisbanes.haze.HazeStyle
import dev.chrisbanes.haze.HazeTint
import dev.chrisbanes.haze.haze
import dev.chrisbanes.haze.hazeChild
import dev.chrisbanes.haze.hazeEffect
import dev.chrisbanes.haze.hazeSource
@Composable
fun SmartHomeScreen() {
val hazeState = HazeState()
Box(
modifier = Modifier
.fillMaxSize()
.background(
Brush.verticalGradient(
colors = listOf(
Color(0xFF1A1A2E),
Color(0xFF16213E),
Color(0xFF0F3460)
)
)
)
.hazeSource(state = hazeState)
) {
// 背景装饰
BackgroundDecoration()
Row(
modifier = Modifier.fillMaxSize()
) {
// 左侧毛玻璃边栏
GlassSidebarWithHaze(
hazeState = hazeState,
modifier = Modifier
.width(260.dp)
.padding(start = 24.dp, top = 24.dp, bottom = 24.dp)
)
Spacer(modifier = Modifier.width(24.dp))
// 主内容区域
MainContentArea(
hazeState = hazeState,
modifier = Modifier
.fillMaxSize()
.padding(end = 24.dp, top = 24.dp, bottom = 24.dp)
)
}
}
}
@Composable
private fun BackgroundDecoration() {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally
) {
repeat(5) { index ->
Box(
modifier = Modifier
.size((100 + index * 20).dp)
.clip(RoundedCornerShape(50))
.background(
Brush.radialGradient(
colors = listOf(
Color(0xFF6C5CE7),
Color(0xFFA29BFE),
Color.Transparent
)
)
)
)
}
}
}
@Composable
private fun GlassSidebarWithHaze(
hazeState: HazeState,
modifier: Modifier = Modifier
) {
Box(
modifier = modifier
.fillMaxHeight()
.clip(RoundedCornerShape(32.dp))
.hazeEffect(
state = hazeState,
style = HazeStyle(
blurRadius = 20.dp,
tint = HazeTint(Color.White.copy(alpha = 0.15f)),
noiseFactor = 0.0f
)
)
.padding(32.dp)
) {
Column(
verticalArrangement = Arrangement.SpaceBetween
) {
Column {
Text(
text = "Lumina",
color = Color.White,
fontSize = 32.sp,
fontWeight = FontWeight.Bold
)
Text(
text = "Smart Home",
color = Color.White.copy(alpha = 0.6f),
fontSize = 14.sp
)
Spacer(modifier = Modifier.height(48.dp))
listOf(
"🏠 首页" to true,
"🌡️ 温控" to false,
"💡 照明" to false,
"🔒 安全" to false,
"🎬 场景" to false,
"⚙️ 自动化" to false
).forEach { (item, isSelected) ->
Text(
text = item,
color = if (isSelected) Color.White else Color.White.copy(alpha = 0.6f),
fontSize = 16.sp,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 12.dp)
)
}
}
// 底部用户信息
Column {
Row(
verticalAlignment = Alignment.CenterVertically
) {
Box(
modifier = Modifier
.size(40.dp)
.clip(RoundedCornerShape(20))
.background(
Brush.linearGradient(
colors = listOf(
Color(0xFF6C5CE7),
Color(0xFFA29BFE)
)
)
)
)
Spacer(modifier = Modifier.width(12.dp))
Column {
Text(
text = "管理员",
color = Color.White,
fontSize = 14.sp,
fontWeight = FontWeight.Medium
)
Text(
text = "在线",
color = Color.White.copy(alpha = 0.6f),
fontSize = 12.sp
)
}
}
}
}
}
}
@Composable
private fun MainContentArea(
hazeState: HazeState,
modifier: Modifier = Modifier
) {
Column(
modifier = modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(24.dp)
) {
// 顶部状态卡片
StatusCard(hazeState = hazeState)
// 设备网格
LazyVerticalGrid(
columns = GridCells.Fixed(2),
modifier = Modifier.fillMaxSize(),
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
items(6) { index ->
DeviceCard(
index = index,
hazeState = hazeState
)
}
}
}
}
@Composable
private fun StatusCard(hazeState: HazeState) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
.clip(RoundedCornerShape(24.dp))
.hazeEffect(
state = hazeState,
style = HazeStyle(
blurRadius = 25.dp,
tint = HazeTint(Color.White.copy(alpha = 0.2f)),
noiseFactor = 0.0f
)
)
.padding(32.dp)
) {
Column(
verticalArrangement = Arrangement.SpaceBetween
) {
Column {
Text(
text = "智能家居控制中心",
color = Color.White,
fontSize = 24.sp,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(16.dp))
Row(
horizontalArrangement = Arrangement.SpaceEvenly,
modifier = Modifier.fillMaxWidth()
) {
StatusItem("温度", "26°C")
StatusItem("湿度", "65%")
StatusItem("空气质量", "")
}
}
Text(
text = "6 个设备在线",
color = Color.White.copy(alpha = 0.8f),
fontSize = 14.sp
)
}
}
}
@Composable
private fun StatusItem(label: String, value: String) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = value,
color = Color.White,
fontSize = 20.sp,
fontWeight = FontWeight.Bold
)
Text(
text = label,
color = Color.White.copy(alpha = 0.6f),
fontSize = 12.sp
)
}
}
@Composable
private fun DeviceCard(
index: Int,
hazeState: HazeState
) {
val devices = listOf(
"客厅灯" to "💡",
"空调" to "❄️",
"电视" to "📺",
"音响" to "🔊",
"摄像头" to "📹",
"门锁" to "🔒"
)
val (name, icon) = devices[index]
Box(
modifier = Modifier
.fillMaxWidth()
.height(150.dp)
.clip(RoundedCornerShape(20.dp))
.hazeEffect(
state = hazeState,
style = HazeStyle(
blurRadius = 20.dp,
tint = HazeTint(Color.White.copy(alpha = 0.15f)),
noiseFactor = 0.0f
)
)
.padding(20.dp),
contentAlignment = Alignment.Center
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
text = icon,
fontSize = 40.sp
)
Text(
text = name,
color = Color.White,
fontSize = 16.sp,
fontWeight = FontWeight.Medium
)
Text(
text = "开启",
color = Color.White.copy(alpha = 0.8f),
fontSize = 12.sp
)
}
}
}

View File

@ -1,27 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:fitsSystemWindows="false">
<eightbitlab.com.blurview.BlurTarget
android:id="@+id/blurTarget"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.compose.ui.platform.ComposeView
android:id="@+id/composeView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</eightbitlab.com.blurview.BlurTarget>
<eightbitlab.com.blurview.BlurView
android:id="@+id/blurView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
app:blurOverlayColor="@color/glassOverlay" />
</FrameLayout>

View File

@ -1,6 +1,7 @@
plugins {
id("com.android.application") version "8.6.0" apply false
id("org.jetbrains.kotlin.android") version "1.9.24" apply false
id("com.android.application") version "8.9.1" apply false
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
id("org.jetbrains.kotlin.plugin.compose") version "2.1.0" apply false
}
tasks.register("clean", Delete::class) {

View File

@ -16,5 +16,5 @@ dependencyResolutionManagement {
}
}
rootProject.name = "SmartHome"
rootProject.name = "智能家居"
include(":app")