优化界面
This commit is contained in:
parent
bde499ba15
commit
8051ff242a
@ -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")
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
176
app/src/main/java/com/example/smarthome/MainActivityCompose.kt
Normal file
176
app/src/main/java/com/example/smarthome/MainActivityCompose.kt
Normal 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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
215
app/src/main/java/com/example/smarthome/MainActivityHaze.kt
Normal file
215
app/src/main/java/com/example/smarthome/MainActivityHaze.kt
Normal 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
613
app/src/main/java/com/example/smarthome/ui/RoomDialog.kt
Normal file
613
app/src/main/java/com/example/smarthome/ui/RoomDialog.kt
Normal 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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 = { /* 添加房间通过对话框内的按钮处理 */ }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
345
app/src/main/java/com/example/smarthome/ui/SmartHomeScreen.kt
Normal file
345
app/src/main/java/com/example/smarthome/ui/SmartHomeScreen.kt
Normal 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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -16,5 +16,5 @@ dependencyResolutionManagement {
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "SmartHome"
|
||||
rootProject.name = "智能家居"
|
||||
include(":app")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user