深入 MaterialTheme:掌握 ColorScheme 与 Typography 的设计核心

技术目标

  1. 会用 MaterialTheme.colorScheme、MaterialTheme.typography 消费设计 token。
  2. 理解 浅色 / 深色 两套 ColorScheme 的切换入口(本仓库:isSystemInDarkTheme())。
  3. 会把 语义色 (primary、tertiary、primaryContainer...)与 组件默认值 对上号,并知道 业务层不直接写死 ARGB 的模块边界。

1. Theme 结构(Material3)

kotlin 复制代码
MaterialTheme(
    colorScheme = if (darkTheme) darkColorScheme() else lightColorScheme(),
    typography = Typography(...),
    shapes = Shapes(...),
) { /* content */ }

Composable 内用 MaterialTheme.colorScheme.primary 等取色;重组 时随上层 MaterialTheme 变化而更新子树。

本仓库入口 ComposeDemoTheme.kt:

  • darkTheme: Boolean = isSystemInDarkTheme():跟随系统深浅色。
  • colorScheme:ComposeDemoLightColors / ComposeDemoDarkColors(lightColorScheme / darkColorScheme 工厂)。
  • typography:ComposeDemoTypography(见同模块 Typography.kt)。

2. 自定义 Token(本仓库模式)

ComposeDemoTokens(与 ComposeDemoTheme 同文件)暴露 跨 feature 复用 的语义:

Token 映射 用途(文档语义)
success colorScheme.tertiary 成功态,不直接写绿
emphasisContainer primaryContainer 强调块、提示条背景
onEmphasisContainer onPrimaryContainer 其上文字色

使用方式:ComposeDemoTokens.emphasisContainer 等 仅在 @Composable 或 @ReadOnlyComposable 上下文中读取 ,内部仍走 MaterialTheme,换主题时一并更新。

边界 :业务/feature 模块依赖 :core:ui 的 Theme + Tokens ,避免在业务里散落 Color(0xFF...);DesignSystemSampleScreen.kt 下半段 硬编码色 仅作反例对照,勿复制到生产。


3. 形状与海拔(Elevation)

Material3 用 tonal elevation 、表面色调表达层次;Surface(tonalElevation = ...) 等与旧 M2「纯 shadow dp」心智不同。升级或混用 M2/M3 时以 官方迁移说明 为准。

本仓库样例屏以 色面 + Typography 为主,未演示复杂 elevation 矩阵;产品上应在设计稿中明确 卡片 / Dialog / BottomSheet 的层级 token。


4. 仓库路径小结

文件 作用
ComposeDemoTheme.kt MaterialTheme 包装 + ComposeDemoTokens
Typography.kt 字阶集中定义
DesignSystemSampleScreen.kt Token 行 vs 硬编码行截图对照

5. 风险清单

  • 硬编码色值 :暗色模式与 对比度(WCAG) 易翻车;无障碍审核会卡。
  • Typography 全表重写 :维护成本高;优先改 titleLarge / bodyLarge 等少数 token,再局部 TextStyle.merge。
  • 三方 SDK 内部写死颜色 :只能 隔离层 包一层或换 SDK,不要假设能 100% Theme 化。
  • LocalContentColor / LocalTextStyle 未随父级更新 :自定义容器时记得向子树提供正确 CompositionLocal。

6. 自检清单

  1. 新 UI 是否 优先 MaterialTheme.typography + colorScheme,仅 token 不足时才扩展 ComposeDemoTokens?
  2. 深色下 onX 与 X 是否成对检查过可读性?
  3. 设计稿里的「成功 / 警告 / 错误」是否映射到 语义色 而非一次性 RGB?
  4. 预览 Preview 是否包在 ComposeDemoTheme { } 内,避免「预览正常、进 App 全黑/全白」?

参考答案(复习用)

  1. 是 。先 MaterialTheme.typography.* / colorScheme.*;跨模块复用语义再抽到 ComposeDemoTokens(如 success → tertiary),避免业务文件里 Color(0xFF...)。
  2. 应检查 。浅色用的 onPrimary 在深色 scheme 里已重新配对;自检时切换系统深色或强制 darkTheme = true 看正文与背景对比度。
  3. 应映射到语义 token (如 error、errorContainer、tertiary),便于深浅色一起换;一次性 RGB 只保留在 Theme 定义文件 或设计工具导出层。
  4. 是 。@Preview 根节点用与 MainActivity 相同的 ComposeDemoTheme { YourScreen() },否则 Preview 可能仍用默认 M3 或未套 colorScheme,与真机不一致。

源码仓库 :ComposeDemo(分支 main)

系列推荐

《副作用 API:LaunchedEffect、DisposableEffect、SideEffect》

《LazyColumn 懒加载、items 与 key》

相关推荐
Dovis(誓平步青云)2 小时前
家里设备越来越多,如何用一张空间地图控制灯光和温度![
android·java·前端·javascript·人工智能·电脑
晚风叙码4 小时前
MySQL 数据类型详解:从数值到字符串,一篇讲透
android·mysql·adb
传奇开心果编程4 小时前
【Compose Multiplatform 跨端开发学与练】第3课 布局与组件
android·windows·学习·ui·ios·kotlin·composer
事圆则缓5 小时前
Kotlin 入门与面试:从空安全、扩展函数到协程
安全·面试·kotlin
传奇开心果编程7 小时前
【现代声明式UI学与练】第9课 性能优化——渲染优化、列表优化、内存优化、启动优化
学习·flutter·react native·ui·性能优化·swiftui·android jetpack
传奇开心果编程7 小时前
【Compose Multiplatform 跨端开发学与练】第8课 资源管理与主题
android·windows·学习·ios·kotlin·web·composer
传奇开心果编程8 小时前
【Compose Multiplatform 跨端开发学与练】第9课 测试与调试
android·学习·macos·ios·kotlin·web·composer
传奇开心果编程8 小时前
【Compose Multiplatform 跨端开发学与练】第4课 导航与路由
android·windows·学习·ui·ios·kotlin·composer
传奇开心果编程9 小时前
【Compose Multiplatform 跨端开发学与练】第6课 状态管理与架构
android·学习·ui·ios·架构·kotlin·composer
事圆则缓9 小时前
Android AOSP 定制常见概念:源码目录、系统镜像与刷机流程
android