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

技术目标

  1. 会用 MaterialTheme.colorSchemeMaterialTheme.typography 消费设计 token。
  2. 理解 浅色 / 深色 两套 ColorScheme 的切换入口(本仓库:isSystemInDarkTheme())。
  3. 会把 语义色primarytertiaryprimaryContainer...)与 组件默认值 对上号,并知道 业务层不直接写死 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():跟随系统深浅色。
  • colorSchemeComposeDemoLightColors / ComposeDemoDarkColorslightColorScheme / darkColorScheme 工厂)。
  • typographyComposeDemoTypography(见同模块 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(如 successtertiary),避免业务文件里 Color(0xFF...)
  2. 应检查 。浅色用的 onPrimary 在深色 scheme 里已重新配对;自检时切换系统深色或强制 darkTheme = true 看正文与背景对比度。
  3. 应映射到语义 token (如 errorerrorContainertertiary),便于深浅色一起换;一次性 RGB 只保留在 Theme 定义文件 或设计工具导出层。
  4. @Preview 根节点用与 MainActivity 相同的 ComposeDemoTheme { YourScreen() },否则 Preview 可能仍用默认 M3 或未套 colorScheme,与真机不一致。

源码仓库ComposeDemo(分支 main

系列推荐

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

《LazyColumn 懒加载、items 与 key》

相关推荐
阿巴斯甜1 小时前
必看2
android
重生之小比特2 小时前
【MySQL 数据库】复合查询
android·数据库·mysql
6666v62 小时前
Kotlin 密封类 (Sealed Class)
kotlin
用户86022504674722 小时前
Jetpack Activity 完整示例教程
android
simplepeng2 小时前
如何减少 89% 的重组,每个Compose开发者都需要的技巧 - derivedStateOf
android·android jetpack
Android 开发者2 小时前
这次,Android 大有不同
android
A8ai2 小时前
Gemini大升级、AI眼镜首发、Android XR亮相,13天后见分晓
android·人工智能·xr
YF02113 小时前
Android 物理摇杆按键映射技术详解
android·游戏
Kapaseker3 小时前
Kotlin inline:你以为它只是个性能优化?
android·kotlin