mirror of
http://180.163.74.83:13000/zhangzhenghao/MPVN_Android.git
synced 2025-12-18 01:34:36 +00:00
增加天气 ip 查询
This commit is contained in:
parent
6393df34ea
commit
0b4fbe3be2
@ -68,6 +68,9 @@ dependencies {
|
|||||||
implementation("androidx.compose.material3:material3-window-size-class:1.3.0")
|
implementation("androidx.compose.material3:material3-window-size-class:1.3.0")
|
||||||
|
|
||||||
implementation("com.github.Dimezis:BlurView:version-3.2.0")
|
implementation("com.github.Dimezis:BlurView:version-3.2.0")
|
||||||
|
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")
|
||||||
|
|
||||||
debugImplementation("com.squareup.leakcanary:leakcanary-android:2.12")
|
debugImplementation("com.squareup.leakcanary:leakcanary-android:2.12")
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,13 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".SmartHomeApp"
|
android:name=".SmartHomeApp"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="SmartHome"
|
android:label="TZSmartHome"
|
||||||
android:theme="@style/Theme.SmartHome">
|
android:theme="@style/Theme.SmartHome">
|
||||||
<activity android:name=".MainActivity"
|
<activity android:name=".MainActivity"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
|||||||
@ -66,6 +66,8 @@ import androidx.compose.animation.core.infiniteRepeatable
|
|||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.core.LinearEasing
|
import androidx.compose.animation.core.LinearEasing
|
||||||
import androidx.compose.animation.core.RepeatMode
|
import androidx.compose.animation.core.RepeatMode
|
||||||
|
import com.example.smarthome.data.WeatherService
|
||||||
|
import com.example.smarthome.data.WeatherInfo
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainScaffold(
|
fun MainScaffold(
|
||||||
@ -86,6 +88,10 @@ fun MainScaffold(
|
|||||||
// 根据选中的导航项显示不同的内容
|
// 根据选中的导航项显示不同的内容
|
||||||
when (selectedNavItem) {
|
when (selectedNavItem) {
|
||||||
0 -> DashboardContent(selectedRoom, onRoomSelect, rooms, onAddRoom, onDeleteRoom)
|
0 -> DashboardContent(selectedRoom, onRoomSelect, rooms, onAddRoom, onDeleteRoom)
|
||||||
|
1 -> SceneScreen()
|
||||||
|
2 -> AutomationScreen()
|
||||||
|
3 -> StatisticsScreen()
|
||||||
|
4 -> SecurityScreen()
|
||||||
5 -> SettingsContent()
|
5 -> SettingsContent()
|
||||||
else -> DashboardContent(selectedRoom, onRoomSelect, rooms, onAddRoom, onDeleteRoom)
|
else -> DashboardContent(selectedRoom, onRoomSelect, rooms, onAddRoom, onDeleteRoom)
|
||||||
}
|
}
|
||||||
@ -394,7 +400,7 @@ fun RoomTab(
|
|||||||
val mod = if (selected) {
|
val mod = if (selected) {
|
||||||
base.background(brush = Brush.linearGradient(listOf(Color(0xFFA9F0FF), Color(0xFFB89CFF))))
|
base.background(brush = Brush.linearGradient(listOf(Color(0xFFA9F0FF), Color(0xFFB89CFF))))
|
||||||
} else {
|
} else {
|
||||||
base.background(color = Color(0x22121212))
|
base.background(color = Color(0x50121212))
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
@ -454,7 +460,13 @@ data class Device(val name: String, val sub: String, val icon: Int, val on: Bool
|
|||||||
@Composable
|
@Composable
|
||||||
fun DeviceCard(d: Device) {
|
fun DeviceCard(d: Device) {
|
||||||
var active by remember { mutableStateOf(d.on) }
|
var active by remember { mutableStateOf(d.on) }
|
||||||
Box(modifier = Modifier.height(120.dp).clip(RoundedCornerShape(24.dp)).background(Color(0x26121212)).shadow(12.dp, RoundedCornerShape(24.dp), true).padding(16.dp)) {
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.height(120.dp)
|
||||||
|
.clip(RoundedCornerShape(24.dp))
|
||||||
|
.background(Color(0x50121212))
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(12.dp)) {
|
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||||
Image(painter = painterResource(id = d.icon), contentDescription = null, modifier = Modifier.size(40.dp))
|
Image(painter = painterResource(id = d.icon), contentDescription = null, modifier = Modifier.size(40.dp))
|
||||||
@ -483,7 +495,7 @@ fun Toggle(on: Boolean, change: (Boolean) -> Unit) {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomNav() {
|
fun BottomNav() {
|
||||||
Row(modifier = Modifier.fillMaxWidth().padding(16.dp).clip(RoundedCornerShape(28.dp)).background(Color(0x33121212)).padding(8.dp), horizontalArrangement = Arrangement.SpaceEvenly) {
|
Row(modifier = Modifier.fillMaxWidth().padding(16.dp).clip(RoundedCornerShape(28.dp)).background(Color(0x50121212)).padding(8.dp), horizontalArrangement = Arrangement.SpaceEvenly) {
|
||||||
NavItem("首页", true)
|
NavItem("首页", true)
|
||||||
NavItem("设备", false)
|
NavItem("设备", false)
|
||||||
NavItem("我的", false)
|
NavItem("我的", false)
|
||||||
@ -502,10 +514,10 @@ fun SideNavRail(selectedNavItem: Int = 0, onNavItemSelect: (Int) -> Unit = {}) {
|
|||||||
Column(modifier = Modifier.width(120.dp).fillMaxHeight().padding(12.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
Column(modifier = Modifier.width(120.dp).fillMaxHeight().padding(12.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||||
Spacer(modifier = Modifier.height(48.dp))
|
Spacer(modifier = Modifier.height(48.dp))
|
||||||
NavRailItem("控制台", R.drawable.ic_dashboard, selectedNavItem == 0, onClick = { onNavItemSelect(0) })
|
NavRailItem("控制台", R.drawable.ic_dashboard, selectedNavItem == 0, onClick = { onNavItemSelect(0) })
|
||||||
NavRailItem("最近", R.drawable.ic_recent, selectedNavItem == 1, onClick = { onNavItemSelect(1) })
|
NavRailItem("场景", R.drawable.ic_scene, selectedNavItem == 1, onClick = { onNavItemSelect(1) })
|
||||||
NavRailItem("收藏", R.drawable.ic_bookmark, selectedNavItem == 2, onClick = { onNavItemSelect(2) })
|
NavRailItem("自动化", R.drawable.ic_automation, selectedNavItem == 2, onClick = { onNavItemSelect(2) })
|
||||||
NavRailItem("下载", R.drawable.ic_download, selectedNavItem == 3, onClick = { onNavItemSelect(3) })
|
NavRailItem("统计", R.drawable.ic_statistics, selectedNavItem == 3, onClick = { onNavItemSelect(3) })
|
||||||
NavRailItem("支持", R.drawable.ic_support, selectedNavItem == 4, onClick = { onNavItemSelect(4) })
|
NavRailItem("安全", R.drawable.ic_security, selectedNavItem == 4, onClick = { onNavItemSelect(4) })
|
||||||
NavRailItem("设置", R.drawable.ic_settings, selectedNavItem == 5, onClick = { onNavItemSelect(5) })
|
NavRailItem("设置", R.drawable.ic_settings, selectedNavItem == 5, onClick = { onNavItemSelect(5) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -568,17 +580,117 @@ fun NavRailItem(text: String, iconRes: Int, selected: Boolean, onClick: () -> Un
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TopBar() {
|
fun TopBar() {
|
||||||
|
var weatherInfo by remember { mutableStateOf(WeatherService.getSimulatedWeather()) }
|
||||||
|
var isLoading by remember { mutableStateOf(true) }
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
try {
|
||||||
|
weatherInfo = WeatherService.getWeather()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// 使用模拟数据
|
||||||
|
}
|
||||||
|
isLoading = false
|
||||||
|
}
|
||||||
|
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text(text = "控制台", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = Color.White)
|
Text(text = "控制台", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold, color = Color.White)
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically) {
|
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))
|
WeatherCard(weatherInfo = weatherInfo, isLoading = isLoading)
|
||||||
}
|
|
||||||
GradientButton("+ 添加设备")
|
GradientButton("+ 添加设备")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun WeatherCard(weatherInfo: WeatherInfo, isLoading: Boolean) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.clip(RoundedCornerShape(16.dp))
|
||||||
|
.background(Color(0x50121212))
|
||||||
|
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
// 温度和天气
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Text(
|
||||||
|
text = if (isLoading) "--" else "${weatherInfo.temperature}°C",
|
||||||
|
fontSize = 18.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = Color.White
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = if (isLoading) "加载中" else weatherInfo.weather,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
color = Color(0xFF9AA0A6)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分隔线
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(1.dp)
|
||||||
|
.height(30.dp)
|
||||||
|
.background(Color(0x33FFFFFF))
|
||||||
|
)
|
||||||
|
|
||||||
|
// 湿度
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Text(
|
||||||
|
text = if (isLoading) "--" else "${weatherInfo.humidity}%",
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
color = Color.White
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "湿度",
|
||||||
|
fontSize = 11.sp,
|
||||||
|
color = Color(0xFF9AA0A6)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分隔线
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(1.dp)
|
||||||
|
.height(30.dp)
|
||||||
|
.background(Color(0x33FFFFFF))
|
||||||
|
)
|
||||||
|
|
||||||
|
// 空气质量
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
val aqiColor = when {
|
||||||
|
weatherInfo.aqi <= 50 -> Color(0xFF00E676)
|
||||||
|
weatherInfo.aqi <= 100 -> Color(0xFFFFEB3B)
|
||||||
|
weatherInfo.aqi <= 150 -> Color(0xFFFF9800)
|
||||||
|
else -> Color(0xFFFF5252)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = if (isLoading) "--" else weatherInfo.airQuality,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
color = aqiColor
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = if (isLoading) "AQI" else "AQI ${weatherInfo.aqi}",
|
||||||
|
fontSize = 11.sp,
|
||||||
|
color = Color(0xFF9AA0A6)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 城市
|
||||||
|
Text(
|
||||||
|
text = weatherInfo.city,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
color = Color(0xFFB0B0B0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun GradientButton(text: String, onClick: () -> Unit = {}) {
|
fun GradientButton(text: String, onClick: () -> Unit = {}) {
|
||||||
Box(modifier = Modifier.height(36.dp).clip(RoundedCornerShape(20.dp)).background(Brush.linearGradient(listOf(Color(0xFFA9F0FF), Color(0xFFB89CFF)))).clickable(indication = null, interactionSource = remember { MutableInteractionSource() }) { onClick() }.padding(horizontal = 16.dp), contentAlignment = Alignment.Center) {
|
Box(modifier = Modifier.height(36.dp).clip(RoundedCornerShape(20.dp)).background(Brush.linearGradient(listOf(Color(0xFFA9F0FF), Color(0xFFB89CFF)))).clickable(indication = null, interactionSource = remember { MutableInteractionSource() }) { onClick() }.padding(horizontal = 16.dp), contentAlignment = Alignment.Center) {
|
||||||
@ -641,30 +753,246 @@ fun MyDevicesGrid(selectedRoom: Int, modifier: Modifier = Modifier) {
|
|||||||
fun UsageStatusChart(modifier: Modifier = Modifier, roomName: String = "房间") {
|
fun UsageStatusChart(modifier: Modifier = Modifier, roomName: String = "房间") {
|
||||||
// 根据房间生成不同的数据
|
// 根据房间生成不同的数据
|
||||||
val values = remember(roomName) {
|
val values = remember(roomName) {
|
||||||
List(10) { (10..35).random().toFloat() }
|
List(12) { (15..45).random().toFloat() }
|
||||||
}
|
}
|
||||||
val totalPower = remember(roomName) { (15.0 + Math.random() * 30).toString().take(5) }
|
val maxValue = remember(values) { values.maxOrNull() ?: 45f }
|
||||||
|
val totalPower = remember(roomName) { (15.0 + Math.random() * 30).toString().take(4) }
|
||||||
val totalHours = remember(roomName) { (10 + (Math.random() * 40).toInt()) }
|
val totalHours = remember(roomName) { (10 + (Math.random() * 40).toInt()) }
|
||||||
|
val activeDevices = remember(roomName) { (3 + (Math.random() * 8).toInt()) }
|
||||||
|
val trend = remember(roomName) { if (Math.random() > 0.5) "↑" else "↓" }
|
||||||
|
val trendPercent = remember(roomName) { (5 + (Math.random() * 15).toInt()) }
|
||||||
|
|
||||||
Box(modifier = modifier.height(220.dp).clip(RoundedCornerShape(24.dp)).background(Color(0x26121212)).padding(16.dp)) {
|
Box(
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
modifier = modifier
|
||||||
|
.height(220.dp)
|
||||||
|
.clip(RoundedCornerShape(24.dp))
|
||||||
|
.background(
|
||||||
|
Brush.linearGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color(0x60121212),
|
||||||
|
Color(0x50121212)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.border(
|
||||||
|
width = 1.dp,
|
||||||
|
brush = Brush.linearGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color(0x22FFFFFF),
|
||||||
|
Color(0x0AFFFFFF)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
shape = RoundedCornerShape(24.dp)
|
||||||
|
)
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
|
modifier = Modifier.fillMaxSize()
|
||||||
|
) {
|
||||||
|
// 标题区域
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
Column {
|
Column {
|
||||||
Text(text = "使用状态", fontWeight = FontWeight.SemiBold, color = Color.White)
|
Text(
|
||||||
Text(text = roomName, fontSize = 12.sp, color = Color(0xFF9AA0A6))
|
text = "能耗统计",
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = Color.White,
|
||||||
|
fontSize = 16.sp
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = roomName,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
color = Color(0xFF9AA0A6)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(24.dp)) {
|
|
||||||
Column {
|
// 趋势指示器
|
||||||
Text(text = "${totalPower}kWh", color = Color.White)
|
Box(
|
||||||
Text(text = "总消耗", color = Color(0xFF9AA0A6), fontSize = 12.sp)
|
modifier = Modifier
|
||||||
}
|
.clip(RoundedCornerShape(12.dp))
|
||||||
Column {
|
.background(
|
||||||
Text(text = "${totalHours}h", color = Color.White)
|
if (trend == "↑") Color(0x33FF5252) else Color(0x3300E676)
|
||||||
Text(text = "总时长", color = Color(0xFF9AA0A6), fontSize = 12.sp)
|
)
|
||||||
|
.padding(horizontal = 10.dp, vertical = 6.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = trend,
|
||||||
|
color = if (trend == "↑") Color(0xFFFF5252) else Color(0xFF00E676),
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "${trendPercent}%",
|
||||||
|
color = if (trend == "↑") Color(0xFFFF5252) else Color(0xFF00E676),
|
||||||
|
fontSize = 12.sp,
|
||||||
|
fontWeight = FontWeight.Medium
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.Bottom) {
|
}
|
||||||
values.forEach { v ->
|
|
||||||
Box(modifier = Modifier.weight(1f).height(v.dp).clip(RoundedCornerShape(6.dp)).background(Color(0xFF2A2A2A)))
|
// 数据指标区域
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
|
) {
|
||||||
|
// 总消耗
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.Bottom,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = totalPower,
|
||||||
|
color = Color(0xFFA9F0FF),
|
||||||
|
fontSize = 20.sp,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "kWh",
|
||||||
|
color = Color(0xFF9AA0A6),
|
||||||
|
fontSize = 12.sp,
|
||||||
|
modifier = Modifier.padding(bottom = 2.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = "总消耗",
|
||||||
|
color = Color(0xFF9AA0A6),
|
||||||
|
fontSize = 11.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行时长
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.Bottom,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "$totalHours",
|
||||||
|
color = Color(0xFFB89CFF),
|
||||||
|
fontSize = 20.sp,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "小时",
|
||||||
|
color = Color(0xFF9AA0A6),
|
||||||
|
fontSize = 12.sp,
|
||||||
|
modifier = Modifier.padding(bottom = 2.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = "运行时长",
|
||||||
|
color = Color(0xFF9AA0A6),
|
||||||
|
fontSize = 11.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 活跃设备
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.Bottom,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "$activeDevices",
|
||||||
|
color = Color(0xFF00E676),
|
||||||
|
fontSize = 20.sp,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "台",
|
||||||
|
color = Color(0xFF9AA0A6),
|
||||||
|
fontSize = 12.sp,
|
||||||
|
modifier = Modifier.padding(bottom = 2.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = "活跃设备",
|
||||||
|
color = Color(0xFF9AA0A6),
|
||||||
|
fontSize = 11.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
|
||||||
|
// 图表区域
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(1f)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.align(Alignment.BottomCenter),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||||
|
verticalAlignment = Alignment.Bottom
|
||||||
|
) {
|
||||||
|
values.forEachIndexed { index, v ->
|
||||||
|
val normalizedHeight = (v / maxValue) * 60
|
||||||
|
val isHighlight = index == values.size - 1
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.height(normalizedHeight.dp)
|
||||||
|
.clip(RoundedCornerShape(topStart = 4.dp, topEnd = 4.dp))
|
||||||
|
.background(
|
||||||
|
if (isHighlight) {
|
||||||
|
Brush.verticalGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color(0xFFA9F0FF),
|
||||||
|
Color(0xFF00D1FF)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Brush.verticalGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color(0xFF3A3A3A),
|
||||||
|
Color(0xFF2A2A2A)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 时间标签
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.align(Alignment.BottomCenter)
|
||||||
|
.offset(y = 16.dp),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "12h前",
|
||||||
|
fontSize = 10.sp,
|
||||||
|
color = Color(0xFF666666)
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "现在",
|
||||||
|
fontSize = 10.sp,
|
||||||
|
color = Color(0xFFA9F0FF),
|
||||||
|
fontWeight = FontWeight.Medium
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -676,7 +1004,7 @@ fun AirConditionerCard(modifier: Modifier = Modifier, roomName: String = "房间
|
|||||||
var temp by remember { mutableStateOf(24f) }
|
var temp by remember { mutableStateOf(24f) }
|
||||||
var isOn by remember { mutableStateOf(true) }
|
var isOn by remember { mutableStateOf(true) }
|
||||||
|
|
||||||
Box(modifier = modifier.height(220.dp).clip(RoundedCornerShape(24.dp)).background(Color(0x26121212)).padding(16.dp)) {
|
Box(modifier = modifier.height(220.dp).clip(RoundedCornerShape(24.dp)).background(Color(0x50121212)).padding(16.dp)) {
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||||
Row(horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
|
||||||
Column {
|
Column {
|
||||||
@ -704,7 +1032,7 @@ fun AirConditionerCard(modifier: Modifier = Modifier, roomName: String = "房间
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(40.dp)
|
.size(40.dp)
|
||||||
.clip(RoundedCornerShape(12.dp))
|
.clip(RoundedCornerShape(12.dp))
|
||||||
.background(Color(0x33FFFFFF))
|
.background(Color(0x55FFFFFF))
|
||||||
.clickable(enabled = isOn && temp > 16f) {
|
.clickable(enabled = isOn && temp > 16f) {
|
||||||
if (temp > 16f) temp -= 1f
|
if (temp > 16f) temp -= 1f
|
||||||
},
|
},
|
||||||
@ -718,7 +1046,7 @@ fun AirConditionerCard(modifier: Modifier = Modifier, roomName: String = "房间
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(40.dp)
|
.size(40.dp)
|
||||||
.clip(RoundedCornerShape(12.dp))
|
.clip(RoundedCornerShape(12.dp))
|
||||||
.background(Color(0x33FFFFFF))
|
.background(Color(0x55FFFFFF))
|
||||||
.clickable(enabled = isOn && temp < 32f) {
|
.clickable(enabled = isOn && temp < 32f) {
|
||||||
if (temp < 32f) temp += 1f
|
if (temp < 32f) temp += 1f
|
||||||
},
|
},
|
||||||
@ -777,10 +1105,10 @@ fun CustomSlider(
|
|||||||
activeTrackColor = Brush.linearGradient(
|
activeTrackColor = Brush.linearGradient(
|
||||||
listOf(Color(0xFF00D1FF), Color(0xFFA9F0FF))
|
listOf(Color(0xFF00D1FF), Color(0xFFA9F0FF))
|
||||||
).let { Color(0xFF00D1FF) },
|
).let { Color(0xFF00D1FF) },
|
||||||
inactiveTrackColor = Color(0x33FFFFFF),
|
inactiveTrackColor = Color(0x55FFFFFF),
|
||||||
disabledThumbColor = Color(0x66FFFFFF),
|
disabledThumbColor = Color(0x66FFFFFF),
|
||||||
disabledActiveTrackColor = Color(0x33FFFFFF),
|
disabledActiveTrackColor = Color(0x55FFFFFF),
|
||||||
disabledInactiveTrackColor = Color(0x22FFFFFF)
|
disabledInactiveTrackColor = Color(0x55FFFFFF)
|
||||||
),
|
),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@ -806,7 +1134,7 @@ fun CustomSlider(
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(if (enabled) Color(0x33FFFFFF) else Color(0x22FFFFFF))
|
.background(if (enabled) Color(0x55FFFFFF) else Color(0x55FFFFFF))
|
||||||
)
|
)
|
||||||
// 激活轨道
|
// 激活轨道
|
||||||
Box(
|
Box(
|
||||||
@ -820,7 +1148,7 @@ fun CustomSlider(
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Brush.linearGradient(
|
Brush.linearGradient(
|
||||||
listOf(Color(0x33FFFFFF), Color(0x33FFFFFF))
|
listOf(Color(0x55FFFFFF), Color(0x55FFFFFF))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -843,9 +1171,9 @@ fun LightList(modifier: Modifier = Modifier) {
|
|||||||
Column(modifier = modifier.fillMaxHeight(), verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
Column(modifier = modifier.fillMaxHeight(), verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||||
Text(text = "灯光", fontWeight = FontWeight.SemiBold)
|
Text(text = "灯光", fontWeight = FontWeight.SemiBold)
|
||||||
lights.forEach { (name, percent) ->
|
lights.forEach { (name, percent) ->
|
||||||
Row(horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.clip(RoundedCornerShape(16.dp)).background(Color(0x26121212)).padding(12.dp)) {
|
Row(horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.clip(RoundedCornerShape(16.dp)).background(Color(0x50121212)).padding(12.dp)) {
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically) {
|
Row(horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||||
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(0x50121212)))
|
||||||
Column { Text(text = name); Text(text = "${(percent * 100).toInt()}%", color = Color(0xFF9AA0A6)) }
|
Column { Text(text = name); Text(text = "${(percent * 100).toInt()}%", color = Color(0xFF9AA0A6)) }
|
||||||
}
|
}
|
||||||
DotsProgress(percent)
|
DotsProgress(percent)
|
||||||
@ -965,6 +1293,14 @@ fun ModeButton(
|
|||||||
val interaction = remember { MutableInteractionSource() }
|
val interaction = remember { MutableInteractionSource() }
|
||||||
var pressed by remember { mutableStateOf(false) }
|
var pressed by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
// 根据文本确定图标
|
||||||
|
val iconRes = when (text) {
|
||||||
|
"回家" -> R.drawable.ic_mode_home
|
||||||
|
"出门" -> R.drawable.ic_mode_away
|
||||||
|
"玩乐" -> R.drawable.ic_mode_fun
|
||||||
|
else -> R.drawable.ic_dashboard
|
||||||
|
}
|
||||||
|
|
||||||
val scale by androidx.compose.animation.core.animateFloatAsState(
|
val scale by androidx.compose.animation.core.animateFloatAsState(
|
||||||
targetValue = if (pressed) 0.96f else 1f,
|
targetValue = if (pressed) 0.96f else 1f,
|
||||||
animationSpec = androidx.compose.animation.core.spring(
|
animationSpec = androidx.compose.animation.core.spring(
|
||||||
@ -980,6 +1316,14 @@ fun ModeButton(
|
|||||||
label = "elevation"
|
label = "elevation"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val iconScale by androidx.compose.animation.core.animateFloatAsState(
|
||||||
|
targetValue = if (selected) 1.1f else 1f,
|
||||||
|
animationSpec = androidx.compose.animation.core.spring(
|
||||||
|
dampingRatio = androidx.compose.animation.core.Spring.DampingRatioMediumBouncy
|
||||||
|
),
|
||||||
|
label = "icon_scale"
|
||||||
|
)
|
||||||
|
|
||||||
val view = LocalView.current
|
val view = LocalView.current
|
||||||
|
|
||||||
LaunchedEffect(interaction) {
|
LaunchedEffect(interaction) {
|
||||||
@ -995,38 +1339,25 @@ fun ModeButton(
|
|||||||
modifier = modifier
|
modifier = modifier
|
||||||
.height(height)
|
.height(height)
|
||||||
.scale(scale)
|
.scale(scale)
|
||||||
.shadow(elevation, shape)
|
.clip(shape)
|
||||||
.background(
|
.then(
|
||||||
if (selected) {
|
if (selected) {
|
||||||
brush
|
Modifier
|
||||||
} else {
|
.shadow(elevation, shape, clip = false)
|
||||||
Brush.linearGradient(
|
.background(brush, shape)
|
||||||
listOf(
|
|
||||||
Color(0x40FFFFFF),
|
|
||||||
Color(0x20FFFFFF)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
shape = shape
|
|
||||||
)
|
|
||||||
.border(
|
.border(
|
||||||
width = if (selected) 2.dp else 1.dp,
|
width = 2.dp,
|
||||||
brush = if (selected) {
|
brush = Brush.linearGradient(
|
||||||
Brush.linearGradient(
|
|
||||||
listOf(
|
listOf(
|
||||||
Color(0x99FFFFFF),
|
Color(0x99FFFFFF),
|
||||||
Color(0x66FFFFFF)
|
Color(0x66FFFFFF)
|
||||||
)
|
)
|
||||||
|
),
|
||||||
|
shape = shape
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Brush.linearGradient(
|
Modifier.background(Color(0x50121212))
|
||||||
listOf(
|
}
|
||||||
Color(0x33FFFFFF),
|
|
||||||
Color(0x11FFFFFF)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
shape = shape
|
|
||||||
)
|
)
|
||||||
.clickable(indication = null, interactionSource = interaction) {
|
.clickable(indication = null, interactionSource = interaction) {
|
||||||
view.playSoundEffect(SoundEffectConstants.CLICK)
|
view.playSoundEffect(SoundEffectConstants.CLICK)
|
||||||
@ -1035,14 +1366,96 @@ fun ModeButton(
|
|||||||
.padding(24.dp),
|
.padding(24.dp),
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
|
) {
|
||||||
|
// 图标容器
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(if (selected) 72.dp else 64.dp)
|
||||||
|
.scale(iconScale),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
// 外层光晕效果(仅选中时)
|
||||||
|
if (selected) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.clip(RoundedCornerShape(20.dp))
|
||||||
|
.background(
|
||||||
|
Brush.radialGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color.White.copy(alpha = 0.2f),
|
||||||
|
Color.Transparent
|
||||||
|
),
|
||||||
|
radius = 100f
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图标背景
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(if (selected) 64.dp else 56.dp)
|
||||||
|
.clip(RoundedCornerShape(18.dp))
|
||||||
|
.background(
|
||||||
|
if (selected) {
|
||||||
|
Brush.linearGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color.White.copy(alpha = 0.25f),
|
||||||
|
Color.White.copy(alpha = 0.15f)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Brush.linearGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color(0x55FFFFFF),
|
||||||
|
Color(0x55FFFFFF)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
if (selected) {
|
||||||
|
Modifier.border(
|
||||||
|
width = 1.dp,
|
||||||
|
brush = Brush.linearGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color.White.copy(alpha = 0.4f),
|
||||||
|
Color.White.copy(alpha = 0.1f)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
shape = RoundedCornerShape(18.dp)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Modifier
|
||||||
|
}
|
||||||
|
),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = iconRes),
|
||||||
|
contentDescription = text,
|
||||||
|
modifier = Modifier.size(if (selected) 38.dp else 34.dp),
|
||||||
|
colorFilter = androidx.compose.ui.graphics.ColorFilter.tint(
|
||||||
|
Color.White
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文字
|
||||||
Text(
|
Text(
|
||||||
text = text,
|
text = text,
|
||||||
color = if (selected) Color.White else Color(0xFFB0B0B0),
|
color = Color.White,
|
||||||
fontWeight = if (selected) FontWeight.Bold else FontWeight.Medium,
|
fontWeight = if (selected) FontWeight.Bold else FontWeight.Medium,
|
||||||
fontSize = if (selected) 22.sp else 20.sp,
|
fontSize = if (selected) 20.sp else 18.sp,
|
||||||
style = MaterialTheme.typography.titleLarge
|
style = MaterialTheme.typography.titleMedium
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -1065,7 +1478,7 @@ fun LightRow(modifier: Modifier = Modifier, roomName: String = "房间") {
|
|||||||
fun LightCard(name: String, percent: Float, modifier: Modifier = Modifier) {
|
fun LightCard(name: String, percent: Float, modifier: Modifier = Modifier) {
|
||||||
var brightness by remember { mutableStateOf(percent) }
|
var brightness by remember { mutableStateOf(percent) }
|
||||||
|
|
||||||
Box(modifier = modifier.height(100.dp).clip(RoundedCornerShape(16.dp)).background(Color(0x26121212)).padding(12.dp)) {
|
Box(modifier = modifier.height(100.dp).clip(RoundedCornerShape(16.dp)).background(Color(0x50121212)).padding(12.dp)) {
|
||||||
Row(horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically) {
|
Row(horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||||
// 灯光图标 - 带发光效果
|
// 灯光图标 - 带发光效果
|
||||||
@ -1142,7 +1555,6 @@ fun AddRoomDialog(
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(Color(0x80000000))
|
|
||||||
.clickable(
|
.clickable(
|
||||||
indication = null,
|
indication = null,
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
@ -1176,8 +1588,8 @@ fun AddRoomDialog(
|
|||||||
placeholder = { Text("请输入房间名称", color = Color(0xFF9AA0A6)) },
|
placeholder = { Text("请输入房间名称", color = Color(0xFF9AA0A6)) },
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
colors = androidx.compose.material3.TextFieldDefaults.colors(
|
colors = androidx.compose.material3.TextFieldDefaults.colors(
|
||||||
focusedContainerColor = Color(0x22FFFFFF),
|
focusedContainerColor = Color(0x55FFFFFF),
|
||||||
unfocusedContainerColor = Color(0x22FFFFFF),
|
unfocusedContainerColor = Color(0x55FFFFFF),
|
||||||
focusedTextColor = Color.White,
|
focusedTextColor = Color.White,
|
||||||
unfocusedTextColor = Color.White,
|
unfocusedTextColor = Color.White,
|
||||||
cursorColor = Color(0xFFA9F0FF),
|
cursorColor = Color(0xFFA9F0FF),
|
||||||
@ -1197,7 +1609,7 @@ fun AddRoomDialog(
|
|||||||
.weight(1f)
|
.weight(1f)
|
||||||
.height(48.dp)
|
.height(48.dp)
|
||||||
.clip(RoundedCornerShape(12.dp))
|
.clip(RoundedCornerShape(12.dp))
|
||||||
.background(Color(0x22FFFFFF))
|
.background(Color(0x55FFFFFF))
|
||||||
.clickable(
|
.clickable(
|
||||||
indication = null,
|
indication = null,
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
|
|||||||
@ -130,7 +130,7 @@ fun SettingsTopBar(onBack: () -> Unit) {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(40.dp)
|
.size(40.dp)
|
||||||
.clip(RoundedCornerShape(12.dp))
|
.clip(RoundedCornerShape(12.dp))
|
||||||
.background(Color(0x22FFFFFF))
|
.background(Color(0x50121212))
|
||||||
.clickable(
|
.clickable(
|
||||||
indication = null,
|
indication = null,
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
@ -167,7 +167,7 @@ fun SettingsSection(title: String, content: @Composable ColumnScope.() -> Unit)
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clip(RoundedCornerShape(24.dp))
|
.clip(RoundedCornerShape(24.dp))
|
||||||
.background(Color(0x26FFFFFF))
|
.background(Color(0x50121212))
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
@ -190,7 +190,7 @@ fun SettingsItem(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clip(RoundedCornerShape(16.dp))
|
.clip(RoundedCornerShape(16.dp))
|
||||||
.background(Color(0x11FFFFFF))
|
.background(Color(0x33121212))
|
||||||
.clickable(
|
.clickable(
|
||||||
indication = null,
|
indication = null,
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
@ -237,7 +237,7 @@ fun SettingsSwitchItem(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clip(RoundedCornerShape(16.dp))
|
.clip(RoundedCornerShape(16.dp))
|
||||||
.background(Color(0x11FFFFFF))
|
.background(Color(0x33121212))
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
@ -312,13 +312,13 @@ fun LogoutButton(onClick: () -> Unit) {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.height(56.dp)
|
.height(56.dp)
|
||||||
|
.shadow(8.dp, RoundedCornerShape(24.dp))
|
||||||
.clip(RoundedCornerShape(24.dp))
|
.clip(RoundedCornerShape(24.dp))
|
||||||
.background(
|
.background(
|
||||||
Brush.linearGradient(
|
Brush.linearGradient(
|
||||||
listOf(Color(0xFFFF6B6B), Color(0xFFFF5252))
|
listOf(Color(0xFFFF6B6B), Color(0xFFFF5252))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.shadow(8.dp, RoundedCornerShape(24.dp), clip = false)
|
|
||||||
.clickable(
|
.clickable(
|
||||||
indication = null,
|
indication = null,
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
|
|||||||
@ -1,3 +1,22 @@
|
|||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
<solid android:color="#121212"/>
|
android:width="108dp"
|
||||||
</shape>
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
|
||||||
|
<!-- 渐变背景 -->
|
||||||
|
<path
|
||||||
|
android:pathData="M0,0 h108 v108 h-108 z">
|
||||||
|
<aapt:attr name="android:fillColor" xmlns:aapt="http://schemas.android.com/aapt">
|
||||||
|
<gradient
|
||||||
|
android:startY="0"
|
||||||
|
android:startX="0"
|
||||||
|
android:endY="108"
|
||||||
|
android:endX="108"
|
||||||
|
android:type="linear">
|
||||||
|
<item android:offset="0" android:color="#FF1A1A2E"/>
|
||||||
|
<item android:offset="1" android:color="#FF16213E"/>
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
</vector>
|
||||||
|
|||||||
@ -1,4 +1,46 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="108dp" android:height="108dp" android:viewportWidth="108" android:viewportHeight="108">
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
<path android:pathData="M24,54 L84,54" android:strokeColor="#FFFFFFFF" android:strokeWidth="6" android:fillColor="#00000000"/>
|
android:width="108dp"
|
||||||
<path android:pathData="M54,24 L54,84" android:strokeColor="#FFFFFFFF" android:strokeWidth="6" android:fillColor="#00000000"/>
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
|
||||||
|
<group
|
||||||
|
android:scaleX="0.08"
|
||||||
|
android:scaleY="0.08"
|
||||||
|
android:translateX="22"
|
||||||
|
android:translateY="22">
|
||||||
|
|
||||||
|
<!-- 中心圆 -->
|
||||||
|
<path
|
||||||
|
android:fillColor="#bfbfbf"
|
||||||
|
android:pathData="M512,540.44 m-312.89,0 a312.89,312.89 0,1,0 625.78,0 a312.89,312.89 0,1,0 -625.78,0 Z"/>
|
||||||
|
|
||||||
|
<!-- 中心环 -->
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M512,398.22 c227.56,0 412.44,56.89 412.44,128 S739.56,654.22 512,654.22 99.56,597.33 99.56,526.22 284.44,398.22 512,398.22 m0,-56.89 c-174.36,0 -469.33,38.97 -469.33,184.89 S337.64,711.11 512,711.11 s469.33,-38.97 469.33,-184.89 S686.36,341.33 512,341.33 z"/>
|
||||||
|
|
||||||
|
<!-- 左侧轨道 -->
|
||||||
|
<path
|
||||||
|
android:fillColor="#7dc5eb"
|
||||||
|
android:pathData="M312.89,117.48 a102.68,102.68 0,0,0 -56.89,16.5 c-36.12,23.89 -71.4,80.21 -32.71,213.9 a1077.48,1077.48 0,0,0 135.96,279.89 c93.01,142.22 241.78,307.2 354.99,307.2 a102.68,102.68 0,0,0 56.89,-16.5 c36.12,-23.89 71.4,-80.21 32.71,-213.9 a1077.48,1077.48 0,0,0 -135.96,-279.89 C573.44,284.44 424.68,117.48 312.89,117.48 z"/>
|
||||||
|
|
||||||
|
<!-- 右侧轨道 -->
|
||||||
|
<path
|
||||||
|
android:fillColor="#e89abe"
|
||||||
|
android:pathData="M695.18,106.38 c113.78,0 256,176.36 343.32,327.4 s200.82,426.67 74.52,498.92 a102.12,102.12 0,0,1 -51.48,13.37 c-113.78,0 -256,-176.36 -343.32,-327.4 s-200.82,-426.67 -74.52,-498.92 a102.12,102.12 0,0,1 51.48,-13.37 z"/>
|
||||||
|
|
||||||
|
<!-- 装饰点 -->
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M170.67,625.78 m-56.89,0 a56.89,56.89 0,1,0 113.78,0 a56.89,56.89 0,1,0 -113.78,0 Z"/>
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M597.33,170.67 m-56.89,0 a56.89,56.89 0,1,0 113.78,0 a56.89,56.89 0,1,0 -113.78,0 Z"/>
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M625.78,881.78 m-56.89,0 a56.89,56.89 0,1,0 113.78,0 a56.89,56.89 0,1,0 -113.78,0 Z"/>
|
||||||
|
</group>
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
|
||||||
</adaptive-icon>
|
|
||||||
Loading…
Reference in New Issue
Block a user