本节摘要:魔法数字是界面失控的起点。本节完成猜数字 App 的设计令牌化:颜色按用途语义化命名并区分明暗两套,尺寸按"间距/字号/圆角"三层分册管理,最后清理代码里残留的硬编码色值。
回看 1.1 节的旧代码,有一行 ForegroundColorSpan(0xFF2E7D32.toInt())——硬编码绿色直接写进逻辑。设计师改版说"成功色换成青绿"的那天,这类散点就是灾难现场。正确做法第一步,把颜色全部语义化收进 colors.xml:
<!-- colors.xml:按用途命名 --> <color name="primary">#3F51B5</color> <color name="on_primary">#FFFFFF</color> <color name="page_bg">#FAFAFA</color> <color name="text_main">#212121</color> <color name="text_secondary">#757575</color> <color name="success">#2E7D32</color> <color name="danger">#C62828</color>
命名法则只有一条:名字说"它是干嘛的",不说"它长什么样"。success 是好名字,green_800 是坏名字——主题换红色系那天,green_800 里装着红色,注释成了谎言。成对命名(primary 与 on_primary)来自 Material 的语义对:一个说底色,一个说"在这个底上放什么前景色",配对使用能保证对比度不翻车,呼应 2.3 节的可访问性红线。
夜间版同名覆盖,构成完整的明暗两套:
<!-- values-night/colors.xml --> <color name="page_bg">#121212</color> <color name="text_main">#E0E0E0</color> <color name="success">#81C784</color>
注意夜间不是简单反转:纯白前景在纯黑底上会刺眼(光晕效应),Material 建议夜间前景压到 E0E0E0 一档、彩色提亮一档,成功色从深绿 2E7D32 提到浅绿 81C784 正是这个逻辑。
代码里的硬编码色值按用途换掉:
// 旧:ForegroundColorSpan(0xFF2E7D32.toInt()) val successColor = ContextCompat.getColor(this, R.color.success) span.setSpan(ForegroundColorSpan(successColor), 0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
dimens.xml 的组织原则是按角色分层,而不是按数值排队:
<!-- dimens.xml --> <!-- 间距层:4 的倍数节奏 --> <dimen name="space_xs">4dp</dimen> <dimen name="space_s">8dp</dimen> <dimen name="space_m">16dp</dimen> <dimen name="space_l">24dp</dimen> <dimen name="space_xl">32dp</dimen> <!-- 字号层:与正文配套 --> <dimen name="font_caption">12sp</dimen> <dimen name="font_body">16sp</dimen> <dimen name="font_title">20sp</dimen> <!-- 形状层 --> <dimen name="radius_button">28dp</dimen> <dimen name="radius_card">12dp</dimen>
间距取 4 的倍数是行业默契(4-8-16-24 构成视觉节奏),一套 space_ 令牌管住全 App 的呼吸感后,"这个间距怎么和别处不一样"这类琐碎返工自然消失。字号必须用 sp(随系统字体设置缩放,2.2 节讲过原理),间距圆角用 dp——令牌化之后单位纪律也顺带固化:引用 @dimen/font_body 的地方不可能是 dp。
⚠️ 常见坑:不要把"所有尺寸"都令牌化。一次性出现的特殊值(某张插画的固定高度)留在原地反而清晰;令牌表膨胀到上百行时,"哪个别处也在用"的心智负担比魔法数更重。判据是复用:第二个地方要用到时才提升为令牌。

设计师给的设计稿变量名和我们令牌名对不上怎么办? 在令牌与原始变量之间建立映射表,落在项目的协作文档里。名字不必强行统一,但映射必须唯一——这一步做完,设计改版从"对着像素找不同"变成"按表改令牌",是团队协作里性价比最高的一小时投资。
令牌化之后还要设计走查吗? 要。令牌管的是一致性,管不了搭配审美——间距全对但节奏呆板、颜色全合规但氛围平淡,这类问题只有走查与迭代能解决。令牌是地基,不是建筑。
收尾再强调一次边界:令牌化服务于复用与一致性,不服务于完美主义。项目初期限于七八个颜色、十几个尺寸是常态,令牌表随需求生长、随重构修剪,像代码一样被版本管理——把它当活文档而不是一次性装修,它的复利才会持续兑现。