Compose主题与样式:Why-Not-Compose中的深色模式实现方案
Compose主题与样式:Why-Not-Compose中的深色模式实现方案
【免费下载链接】Why-Not-ComposeA collection of animations, compositions, UIs using Jetpack Compose. You can say Jetpack Compose cookbook, showcase or play-ground if you want!项目地址: https://gitcode.com/gh_mirrors/wh/Why-Not-Compose
Why-Not-Compose是一个基于Jetpack Compose构建的UI组件与动画集合,提供了丰富的Compose实践案例。本文将深入解析该项目中深色模式的完整实现方案,包括主题架构设计、模式切换逻辑和色彩系统管理,帮助开发者快速掌握Compose应用的主题定制技巧。
主题模式架构设计
Why-Not-Compose采用了灵活的主题模式管理系统,通过枚举类型定义了三种主题状态,满足不同场景下的用户需求。
核心主题模式定义
项目在base/src/main/kotlin/org/imaginativeworld/whynotcompose/base/models/UIThemeMode.kt中定义了主题模式枚举:
enum class UIThemeMode(val value: Int) { AUTO(0), // 跟随系统主题 LIGHT(1), // 强制亮色模式 DARK(2) // 强制暗色模式 }该枚举还提供了实用的扩展方法,如主题切换逻辑和系统主题判断:
// 切换到下一个主题模式 fun UIThemeMode.nextMode() = when (this) { UIThemeMode.AUTO -> UIThemeMode.LIGHT UIThemeMode.LIGHT -> UIThemeMode.DARK UIThemeMode.DARK -> UIThemeMode.AUTO } // 判断当前是否为亮色模式 @Composable fun UIThemeMode.isLight(): Boolean { val isSystemInDarkTheme = isSystemInDarkTheme() return when (this) { UIThemeMode.AUTO -> !isSystemInDarkTheme UIThemeMode.LIGHT -> true UIThemeMode.DARK -> false } }主题状态管理控制器
项目通过单例模式实现了主题状态的全局管理,位于base/src/main/kotlin/org/imaginativeworld/whynotcompose/base/utils/UIThemeController.kt:
object UIThemeController { private val _uiThemeMode = MutableStateFlow(UIThemeMode.AUTO) val uiThemeMode = _uiThemeMode.asStateFlow() fun updateUITheme(themeMode: UIThemeMode) { _uiThemeMode.value = themeMode } }这个控制器使用StateFlow存储和分发主题状态变化,确保整个应用能实时响应主题切换。
色彩系统实现
Why-Not-Compose采用了Material3的色彩系统,并针对亮色和暗色模式定义了不同的色彩方案。
主题色彩配置
在common-ui-compose/src/main/kotlin/org/imaginativeworld/whynotcompose/common/compose/theme/Theme.kt中,项目定义了完整的色彩方案:
// 深色模式色彩方案 private val DarkColorScheme @Composable get() = darkColorScheme( primary = TailwindCSSColor.Green700, secondary = TailwindCSSColor.Pink700, background = TailwindCSSColor.Gray900, surface = Color.Black, error = TailwindCSSColor.Red700, onPrimary = TailwindCSSColor.Gray50, onSecondary = TailwindCSSColor.Gray50, onBackground = TailwindCSSColor.Gray50, onSurface = TailwindCSSColor.Gray50 ) // 亮色模式色彩方案 private val LightColorScheme @Composable get() = lightColorScheme( primary = TailwindCSSColor.Green500, secondary = TailwindCSSColor.Pink500, background = TailwindCSSColor.Gray50, surface = Color.White, error = TailwindCSSColor.Red500, onPrimary = TailwindCSSColor.Gray50, onSecondary = TailwindCSSColor.Gray50, onBackground = TailwindCSSColor.Gray900, onSurface = TailwindCSSColor.Gray900 )动态色彩支持
项目还支持Android 12+的动态色彩功能,根据系统主题自动调整应用色彩:
val colorScheme = when { dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { val context = LocalContext.current if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) } darkTheme -> DarkColorScheme else -> LightColorScheme }主题切换实现
主题切换功能在应用的多个界面中实现,包括主屏幕和CMS模块,提供了一致的用户体验。
主题切换UI组件
在app/src/main/kotlin/org/imaginativeworld/whynotcompose/ui/screens/home/index/HomeIndexScreen.kt中,实现了主题切换按钮:
IconButton( onClick = { val newMode = uiThemeMode.value.nextMode() sharedPref.setDarkMode(newMode) UIThemeController.updateUITheme(newMode) } ) { Icon( painter = painterResource( id = when (uiThemeMode.value) { UIThemeMode.AUTO -> R.drawable.ic_night_sight_auto UIThemeMode.LIGHT -> R.drawable.ic_brightness_high UIThemeMode.DARK -> R.drawable.ic_moon_stars } ), contentDescription = "Toggle theme" ) }主题应用入口
在app/src/main/kotlin/org/imaginativeworld/whynotcompose/ui/screens/MainActivity.kt中,主题应用于整个应用:
setContent { val uiThemeMode by UIThemeController.uiThemeMode.collectAsState() val isDarkMode = when (uiThemeMode) { UIThemeMode.AUTO -> isSystemInDarkTheme() UIThemeMode.LIGHT -> false UIThemeMode.DARK -> true } AppTheme( darkTheme = isDarkMode, dynamicColor = true ) { // 应用内容 } }深色模式效果展示
下面展示了Why-Not-Compose中不同UI组件在深色模式下的效果:
深色模式下的按钮组件展示了高对比度的设计,确保良好的可读性
文本输入框在深色模式下采用了柔和的边框和背景色,减少视觉疲劳
列表组件在深色主题中使用了微妙的背景分层,提升内容可读性
最佳实践总结
Why-Not-Compose的深色模式实现遵循了多项最佳实践:
- 状态驱动设计:使用StateFlow管理主题状态,确保状态变化能够正确反映到UI
- 用户偏好保存:通过SharedPreferences持久化用户主题选择
- 系统主题适配:支持跟随系统主题变化,符合Android设计规范
- 动态色彩支持:利用Android 12+的动态色彩功能,提供更个性化的体验
- 高对比度设计:确保深色模式下文本与背景的对比度符合可访问性标准
通过学习这些实现细节,开发者可以为自己的Compose应用构建出专业、灵活的主题系统,提升用户体验。
要开始使用Why-Not-Compose项目,可通过以下命令克隆仓库:
git clone https://gitcode.com/gh_mirrors/wh/Why-Not-Compose项目中的主题实现代码可以作为Compose应用主题管理的参考范例,帮助开发者快速构建自己的主题系统。
【免费下载链接】Why-Not-ComposeA collection of animations, compositions, UIs using Jetpack Compose. You can say Jetpack Compose cookbook, showcase or play-ground if you want!项目地址: https://gitcode.com/gh_mirrors/wh/Why-Not-Compose
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考