diff --git a/shared/src/commonMain/composeResources/drawable/ic_ring.png b/shared/src/commonMain/composeResources/drawable/ic_ring.png new file mode 100644 index 0000000..ea3a890 Binary files /dev/null and b/shared/src/commonMain/composeResources/drawable/ic_ring.png differ diff --git a/shared/src/commonMain/kotlin/com/whitefish/ring/ui/home/setting/SettingScreen.kt b/shared/src/commonMain/kotlin/com/whitefish/ring/ui/home/setting/SettingScreen.kt index f8a7da6..83c28b2 100644 --- a/shared/src/commonMain/kotlin/com/whitefish/ring/ui/home/setting/SettingScreen.kt +++ b/shared/src/commonMain/kotlin/com/whitefish/ring/ui/home/setting/SettingScreen.kt @@ -1,22 +1,44 @@ package com.whitefish.ring.ui.home.setting +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue 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.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel +import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.ui.tooling.preview.Preview -import kotlin.invoke +import ring.shared.generated.resources.Res +import ring.shared.generated.resources.ic_ring @Composable fun SettingScreen( @@ -24,94 +46,357 @@ fun SettingScreen( viewModel: SettingViewModel = viewModel { SettingViewModel() } ) { val uiState by viewModel.uiState.collectAsState() - - LazyColumn( - modifier = modifier - .fillMaxSize() - .background(Color(0xFF1A1A1A)) - .padding(horizontal = 16.dp), - contentPadding = PaddingValues(vertical = 16.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) + + Box( + modifier = modifier.fillMaxSize() + ) { + LazyColumn( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + item { + Spacer(modifier = Modifier.height(40.dp)) + } + + // 顶部标题和头像 + item { + TopSection( + deviceName = uiState.deviceName, + modifier = Modifier.fillMaxWidth() + ) + } + + // 戒指图像 + item { + RingImageSection( + modifier = Modifier.fillMaxWidth() + ) + } + + // 连接状态和电池 + item { + ConnectionStatusSection( + isConnected = uiState.isConnected, + batteryLevel = uiState.batteryLevel, + modifier = Modifier.fillMaxWidth().height(102.dp) + ) + } + + // 功能网格 - 使用分块显示而不是嵌套LazyGrid + item { + FeatureGridSection( + features = uiState.featureItems, + onFeatureClick = viewModel::onFeatureClick, + modifier = Modifier.fillMaxWidth() + ) + } + + // 其他设置 + item { + OtherSettingsSection( + settingItems = uiState.settingItems, + onSettingClick = viewModel::onSettingClick, + modifier = Modifier.fillMaxWidth() + ) + } + } + } +} + +@Composable +private fun TopSection( + deviceName: String, + modifier: Modifier = Modifier +) { + Row( + modifier = modifier, + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = deviceName, + fontSize = 20.sp, + fontWeight = FontWeight.Medium, + color = Color.White + ) + + // 头像占位符 + Box( + modifier = Modifier + .size(40.dp) + .clip(CircleShape) + .background(Color.White.copy(alpha = 0.3f)), + contentAlignment = Alignment.Center + ) { +// Icon( +// imageVector = Icons.Default.Person, +// contentDescription = "用户头像", +// tint = Color.White, +// modifier = Modifier.size(24.dp) +// ) + } + } +} + +@Composable +private fun RingImageSection( + modifier: Modifier = Modifier +) { + Box( + modifier = modifier, + contentAlignment = Alignment.Center ) { - items(uiState.settingItems) { setting -> - SettingItem( - setting = setting, - onItemClick = { viewModel.onSettingClick(setting) } + // 戒指图像占位符 + Box( + modifier = Modifier + .size(160.dp) + .clip(CircleShape), + contentAlignment = Alignment.Center + ) { + Image( + painter = painterResource(Res.drawable.ic_ring), + contentDescription = null, + modifier = Modifier.fillMaxSize() ) } } } @Composable -private fun SettingItem( - setting: SettingItemData, - onItemClick: () -> Unit, +private fun ConnectionStatusSection( + isConnected: Boolean, + batteryLevel: Int, modifier: Modifier = Modifier ) { Card( - modifier = modifier - .fillMaxWidth() - .clickable { onItemClick() }, - shape = RoundedCornerShape(12.dp), + modifier = modifier, + shape = RoundedCornerShape(15.dp), colors = CardDefaults.cardColors( - containerColor = Color(0xFF2A2A2A) + containerColor = Color.White.copy(alpha = 0.9f) ) ) { Row( modifier = Modifier - .fillMaxWidth() + .fillMaxSize() .padding(16.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { - Column( - modifier = Modifier.weight(1f) + Text( + text = if (isConnected) "已连接" else "未连接", + fontSize = 16.sp, + fontWeight = FontWeight.Medium, + color = Color.Black + ) + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp) ) { + // 电池图标占位符 + Box( + modifier = Modifier + .size(20.dp, 12.dp) + .background( + color = if (batteryLevel > 20) Color.Green else Color.Red, + shape = RoundedCornerShape(2.dp) + ) + ) Text( - text = setting.title, - color = Color.White, + text = "$batteryLevel%", fontSize = 16.sp, - fontWeight = FontWeight.Medium + fontWeight = FontWeight.Medium, + color = Color.Black ) - - if (setting.subtitle.isNotEmpty()) { - Spacer(modifier = Modifier.height(4.dp)) - Text( - text = setting.subtitle, - color = Color.Gray, - fontSize = 14.sp + } + } + } +} + +@Composable +private fun FeatureGridSection( + features: List, + onFeatureClick: (FeatureItemData) -> Unit, + modifier: Modifier = Modifier +) { + // 将features按每行2个分组 + val chunkedFeatures = features.chunked(2) + + Column( + modifier = modifier, + verticalArrangement = Arrangement.spacedBy(12.dp) + ) { + chunkedFeatures.forEach { rowFeatures -> + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(12.dp) + ) { + rowFeatures.forEach { feature -> + FeatureCard( + feature = feature, + onClick = { onFeatureClick(feature) }, + modifier = Modifier.weight(1f) ) } + // 如果行中只有一个元素,添加一个空的spacer保持布局对称 + if (rowFeatures.size == 1) { + Spacer(modifier = Modifier.weight(1f)) + } + } + } + } +} + +@Composable +private fun FeatureCard( + feature: FeatureItemData, + onClick: () -> Unit, + modifier: Modifier = Modifier +) { + Card( + modifier = modifier + .height(85.dp) + .clickable { onClick() }, + shape = RoundedCornerShape(16.dp), + colors = CardDefaults.cardColors( + containerColor = Color.White.copy(alpha = 0.9f) + ) + ) { + + Row(modifier = Modifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically) { + Spacer(Modifier.width(12.dp)) + Column { + Text("Title", fontSize = 18.sp, color = Color(0xff394298)) + Text("Subtitle", fontSize = 11.sp, color = Color(0xff978CB9)) } - - if (setting.hasSwitch) { - Switch( - checked = setting.isEnabled, - onCheckedChange = { /* Handle switch change */ }, - colors = SwitchDefaults.colors( - checkedThumbColor = Color.White, - checkedTrackColor = Color(0xFF352764), - uncheckedThumbColor = Color.Gray, - uncheckedTrackColor = Color.DarkGray + Spacer(modifier = Modifier.weight(1f)) + Column { + // 功能图标占位符 + Box( + modifier = Modifier + .size(32.dp) + .clip(CircleShape) + .background(getFeatureIconColor(feature.id)), + contentAlignment = Alignment.Center + ) { + Text( + text = getFeatureIconText(feature.id), + fontSize = 16.sp, + color = Color.White, + fontWeight = FontWeight.Bold ) + } + } + Spacer(Modifier.width(22.dp)) + + } + } +} + +@Composable +private fun OtherSettingsSection( + settingItems: List, + onSettingClick: (SettingItemData) -> Unit, + modifier: Modifier = Modifier +) { + Column( + modifier = modifier, + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + Text( + text = "其他", + fontSize = 16.sp, + fontWeight = FontWeight.Medium, + color = Color.White, + modifier = Modifier.padding(horizontal = 4.dp) + ) + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp) + ) { + settingItems.forEach { setting -> + SettingItem( + setting = setting, + onClick = { onSettingClick(setting) }, + modifier = Modifier.height(65.dp) ) - } else { - Text( - text = ">", - color = Color.Gray, - fontSize = 18.sp - ) } } } } -data class SettingItemData( - val title: String, - val subtitle: String = "", - val hasSwitch: Boolean = false, - val isEnabled: Boolean = false -) +@Composable +private fun SettingItem( + setting: SettingItemData, + onClick: () -> Unit, + modifier: Modifier = Modifier +) { + Card( + modifier = modifier + .fillMaxWidth() + .clickable { onClick() }, + shape = RoundedCornerShape(20.dp), + colors = CardDefaults.cardColors( + containerColor = Color(0xff352764) + ) + ) { + Row( + modifier = Modifier + .fillMaxSize() + .padding(start = 12.dp,end = 16.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = setting.title, + fontSize = 16.sp, + fontWeight = FontWeight.Medium, + color = Color.White + ) + + if (setting.hasArrow) { +// Icon( +// imageVector = Icons.Default.ArrowForwardIos, +// contentDescription = "前往", +// tint = Color.White, +// modifier = Modifier.size(16.dp) +// ) + } + } + } +} + +// 辅助函数:获取功能图标颜色 +private fun getFeatureIconColor(featureId: String): Color { + return when (featureId) { + "smart_life" -> Color(0xFF4CAF50) + "wallet" -> Color(0xFFFF5722) + "message_notification" -> Color(0xFFFFC107) + "find_device" -> Color(0xFF2196F3) + "alarm" -> Color(0xFFFF9800) + "message_reminder" -> Color(0xFF9C27B0) + "wechat" -> Color(0xFF4CAF50) + "manual" -> Color(0xFF795548) + else -> Color.Gray + } +} + +// 辅助函数:获取功能图标文本 +private fun getFeatureIconText(featureId: String): String { + return when (featureId) { + "smart_life" -> "🏠" + "wallet" -> "💰" + "message_notification" -> "📧" + "find_device" -> "🔍" + "alarm" -> "⏰" + "message_reminder" -> "💡" + "wechat" -> "💬" + "manual" -> "📖" + else -> "?" + } +} @Preview @Composable diff --git a/shared/src/commonMain/kotlin/com/whitefish/ring/ui/home/setting/SettingViewModel.kt b/shared/src/commonMain/kotlin/com/whitefish/ring/ui/home/setting/SettingViewModel.kt index 4781ca4..6924827 100644 --- a/shared/src/commonMain/kotlin/com/whitefish/ring/ui/home/setting/SettingViewModel.kt +++ b/shared/src/commonMain/kotlin/com/whitefish/ring/ui/home/setting/SettingViewModel.kt @@ -4,8 +4,33 @@ import androidx.lifecycle.ViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import org.jetbrains.compose.resources.DrawableResource + +// 功能模块数据类 +data class FeatureItemData( + val id: String, + val title: String, + val icon: DrawableResource? = null, + val isEnabled: Boolean = false, + val hasNotification: Boolean = false, + val onClick: (() -> Unit)? = null +) + +// 设置项数据类 +data class SettingItemData( + val title: String, + val subtitle: String = "", + val hasSwitch: Boolean = false, + val isEnabled: Boolean = false, + val hasArrow: Boolean = true, + val onClick: (() -> Unit)? = null +) data class SettingUiState( + val deviceName: String = "Star Ring Gen1", + val isConnected: Boolean = true, + val batteryLevel: Int = 100, + val featureItems: List = emptyList(), val settingItems: List = emptyList(), val isLoading: Boolean = false ) @@ -16,66 +41,84 @@ class SettingViewModel : ViewModel() { val uiState: StateFlow = _uiState.asStateFlow() init { - loadSettingItems() + loadData() } - private fun loadSettingItems() { - // 模拟加载设置项数据 - val mockData = listOf( - SettingItemData( - title = "设备连接", - subtitle = "管理蓝牙设备连接" - ), - SettingItemData( - title = "数据同步", - subtitle = "自动同步健康数据", - hasSwitch = true, - isEnabled = true - ), - SettingItemData( - title = "通知设置", - subtitle = "运动提醒和健康通知" - ), - SettingItemData( - title = "隐私设置", - subtitle = "数据隐私和权限管理" - ), - SettingItemData( - title = "夜间模式", - subtitle = "自动切换深色主题", - hasSwitch = true, - isEnabled = false - ), - SettingItemData( - title = "关于应用", - subtitle = "版本信息和帮助" - ), - SettingItemData( - title = "退出登录", - subtitle = "" - ) + private fun loadData() { + // 功能模块数据 + val featureItems = listOf( + FeatureItemData("smart_life", "智慧生活\n联动"), + FeatureItemData("wallet", "钱包"), + FeatureItemData("message_notification", "消息通知", hasNotification = true), + FeatureItemData("find_device", "找设备"), + FeatureItemData("alarm", "闹钟"), + FeatureItemData("message_reminder", "消息提醒"), + FeatureItemData("wechat", "微信绑定"), + FeatureItemData("manual", "产品手册") ) - _uiState.value = _uiState.value.copy(settingItems = mockData) + // 设置项数据 + val settingItems = listOf( + SettingItemData("设备设置"), + SettingItemData("恢复出厂设置"), + SettingItemData("固件更新"), + SettingItemData("帮助与客服"), + SettingItemData("设备信息") + ) + + _uiState.value = _uiState.value.copy( + featureItems = featureItems, + settingItems = settingItems + ) + } + + fun onFeatureClick(feature: FeatureItemData) { + // 处理功能项点击事件 + when (feature.id) { + "smart_life" -> { + // 跳转到智慧生活联动页面 + } + "wallet" -> { + // 跳转到钱包页面 + } + "message_notification" -> { + // 跳转到消息通知设置页面 + } + "find_device" -> { + // 执行查找设备功能 + } + "alarm" -> { + // 跳转到闹钟设置页面 + } + "message_reminder" -> { + // 跳转到消息提醒设置页面 + } + "wechat" -> { + // 跳转到微信绑定页面 + } + "manual" -> { + // 打开产品手册 + } + } } fun onSettingClick(setting: SettingItemData) { // 处理设置项点击事件 when (setting.title) { - "设备连接" -> { - // 跳转到设备连接页面 + "设备设置" -> { + // 跳转到设备设置页面 } - "通知设置" -> { - // 跳转到通知设置页面 + "恢复出厂设置" -> { + // 显示恢复出厂设置确认对话框 } - "隐私设置" -> { - // 跳转到隐私设置页面 + "固件更新" -> { + // 跳转到固件更新页面 } - "关于应用" -> { - // 跳转到关于页面 + "帮助与客服" -> { + // 跳转到帮助与客服页面 } - "退出登录" -> { - // 处理退出登录 + "设备信息" -> { + // 跳转到设备信息页面 } } }