# 主题模式切换功能设计 ## 概述 为巡检相机 App 增加主题模式切换选项(跟随系统 / 浅色 / 暗色), 并修复当前暗色模式下字体颜色不可读的问题。 ## 问题分析 - Theme.kt 已定义 LightColorScheme 和 DarkColorScheme - 所有界面使用硬编码 Color 值(Color.White, Color.Black, Color.LightGray, Primary 等) - 未使用 MaterialTheme.colorScheme.* - 暗色模式下主题切换为 DarkColorScheme,但 UI 颜色不变,导致文字不可见 ## 方案:MaterialTheme.colorScheme 统一替换 将所有硬编码颜色替换为 MaterialTheme.colorScheme 提供的语义化颜色。 ### 新增类型 **ThemeMode 枚举**(data/models 包) ```kotlin enum class ThemeMode { FOLLOW_SYSTEM, LIGHT, DARK } ``` ### 修改文件 | 文件 | 改动 | |------|------| | `data/models/WatermarkModels.kt` | 新增 ThemeMode 枚举 | | `data/PreferencesManager.kt` | 新增 KEY_THEME_MODE + themeMode Flow + setThemeMode | | `ui/theme/Theme.kt` | InspectionCameraTheme 接受 themeMode 参数,取代 darkTheme | | `ui/MainActivity.kt` | 读取 themeMode 偏好并传入 InspectionCameraTheme | | `ui/settings/SettingsScreen.kt` | 新增"主题设置"区域,三个 RadioButton | | `ui/camera/CameraScreen.kt` | 替换硬编码颜色 | | `ui/gallery/GalleryScreen.kt` | 替换硬编码颜色 | | `ui/merge/MergeScreen.kt` | 替换硬编码颜色 | ### 颜色替换映射 | 原硬编码颜色 | 替换为 | 说明 | |-------------|--------|------| | `Primary` | `MaterialTheme.colorScheme.primary` | TopAppBar 背景、选中态、强调文字 | | `Color.White` (TopAppBar文字) | `MaterialTheme.colorScheme.onPrimary` | TopAppBar 文字/图标 | | `Color.White` (Card背景) | `MaterialTheme.colorScheme.surface` | Card 容器背景 | | `Color.LightGray` (占位背景) | `MaterialTheme.colorScheme.surfaceVariant` | 网格占位区背景 | | `Color.Gray` (辅助文字) | `MaterialTheme.colorScheme.onSurfaceVariant` | 描述性文字 | | `Color.Black` (primary文字) | `MaterialTheme.colorScheme.onSurface` | 主要文字 | | `Color.Red` (删除) | `MaterialTheme.colorScheme.error` | 删除/错误提示 | | `Color.White` (按钮文字) | `MaterialTheme.colorScheme.onPrimary` | 按钮文字 | | 相机覆盖层颜色 | 保持原样(覆盖在相机预览上,不属于主题背景) | 半透明黑/白色 | ### 相机覆盖层的例外处理 - 相机界面的半透明黑色底部控制栏(`Color.Black.copy(alpha = 0.3f)`)和白色 FAB 按钮**保持不变** - 这些元素覆盖在相机实时预览之上,不属于 App 背景层,不应随主题变化 ### 主题传递流程 ``` SettingsScreen → PreferencesManager.setThemeMode(mode) ↓ MainActivity ← PreferencesManager.themeMode (Flow) ↓ InspectionCameraTheme(themeMode) → 计算是否暗色 ↓ MaterialTheme(colorScheme = light/dark) ↓ 所有界面使用 MaterialTheme.colorScheme.* 获取颜色 ``` ### ThemeMode 逻辑 - `FOLLOW_SYSTEM`: `isSystemInDarkTheme()` 决定 - `LIGHT`: 强制用 LightColorScheme - `DARK`: 强制用 DarkColorScheme