深入 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》

相关推荐
TimeFine3 小时前
AI 编码工作流的设计
android·ai编程
骑着蜗牛撵大象3274 小时前
C++20 协程 × 屏障:手写一个 co_await 版 Barrier,让等待不再钉死线程
android·c++20·协程·并发编程·co_await·屏障同步
山东孙燕姿6 小时前
设备台账重构:从一张表到三层模型
android·java·网络·低代码·重构·rxjava
蒸鱼Yuzheng7 小时前
移动端 CPU 调度分析:线程亲和性、大小核迁移与卡顿
android·perfetto·性能分析·线程优化·cpu调度
booboosui7 小时前
安卓唤醒词:12 维 MFCC 加 DTW,阈值 1.8
android
传奇开心果7 小时前
Compose Multiplatform 共享边界实战:架构契约、互操作同步与可回退设计
android·kotlin
事圆则缓7 小时前
从开机到首帧:Android 系统与应用启动流程源码分析
android
AI吃大瓜7 小时前
指针压力表读数4:Android实现指针压力表读数(可实时检测)
android·指针读数·指针压力表·压力表·压力表读数
fengci.8 小时前
CTF2刷题记录(困难部分)
android·开发语言·前端·学习·php
hunterandroid8 小时前
[Android 从零到一] ARouter 路由框架原理:APT 生成路由表与组件化通信
android