impeccable 原生 Android 设计参考全解:Material Design 3 守则、组件边界与 adb 真机验收实战
2026/9/8 23:33:29 网站建设 项目流程

impeccable 原生 Android 设计参考全解:Material Design 3 守则、组件边界与 adb 真机验收实战

【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccable

导读

impeccable是一个让 AI 前端设计代理产出“非平庸设计”的技能库,它对不同交付平台维护了不同的平台守则。本文以仓库中的平台参考文档 skill/reference/android.md(同名文件同时存在于 .cursor/skills/impeccable/reference/android.md 等各模型提供商的分布式技能目录中)为核心,系统讲解面向 Jetpack Compose、Android Views、React Native、Expo、Flutter 等原生 Android 应用的设计约束:从 Material Design 3 的布局、触控、字体、色彩、动效规范,到“Android slop 测试”,再到用adb在模拟器与真机上截图、切换深色主题、放大字体做交付前验收的完整命令链。读完本文,你能掌握一套可直接执行的“Android 界面是否可信”检查清单,并理解这些规则在 impeccable 路由、审计、评审流程中的落地方式。

一、这份文档在 impeccable 中扮演什么角色

1.1 平台轴(Platform Axis)是独立于模式(Mode)的第二维

在 impeccable 中,用户可见的技能是一个名为impeccable的单一技能,内含 23 个命令(craft、shape、init、audit、polish 等)。CLAUDE.md 明确指出,技能同时维护两条互相正交的轴:

  • 模式(Mode):Persuade / Operate / Read / Experience,回答“访客来这个界面做什么”;
  • 平台(Platform):web / ios / android / adaptive,回答“交付目标是什么、套用哪套原生惯例”。

android.md正是android平台值所对应的规则手册,内容定位是“Material Design 3 的蒸馏版”(distilled)。除 web 外的每个平台都有专属参考文件:

平台触发条件加载的参考文档
web默认值,无需额外规则书技能本体 General 规则
ios原生 iOS / iPadOS 应用skill/reference/ios.md
android原生 Android 应用skill/reference/android.md
adaptive同一套代码同时交付 iOS 与 Android(Flutter、React Native、KMP),且按系统自适应同时加载 ios.md 与 android.md

需要特别强调的是 adaptive 的判定标准:一个“Material-everywhere”的跨平台应用(这正是 Flutter 的默认形态)如果两端长得一模一样,在 impeccable 里不被视为 adaptive,它只取单一平台(通常按 Material 处理)的约束。只有真正“按系统自适应”的跨平台应用,才需要同时吃进两套平台守则。

1.2 文档如何进入 AI 的执行上下文

从 CLAUDE.md 的实现说明可以还原这条加载链路:

  1. 项目根目录的PRODUCT.md中记录## Platform字段,取值只有裸值web/ios/android/adaptive
  2. 技能启动脚本skill/scripts/context.mjs通过extractPlatform()(底层复用通用的extractSectionValue())解析该字段;字段缺失时默认回退为web,保证老项目不受影响;
  3. 当解析结果是iosandroidadaptive时,context.mjs会把对应平台参考文档直接内联进它的输出,也就是说平台惯例无需模型二次读取文档即可进入上下文;
  4. 当用户在原生平台项目上初始化(init)时,skill/reference/init.md 会在确认平台后自行加载对应平台参考文档(见其“Step 3/Step 4”描述),因为新项目在写入 PRODUCT.md 之前,context.mjs无从得知平台,init 是唯一能学到答案的地方;
  5. 如果一个工作区携带原生构建文件、却继承了指向 web 的根 PRODUCT.md,skill/reference/doctor.md 会把它登记为最重要的workspace-platform-native-evidence类漂移问题,修复方式是给该工作区补一份子 PRODUCT.md,因为“一份继承来的记录无法同时承载两个平台”。

此外,NOTICE.md 记录了文档出处:skill/reference/ios.mdskill/reference/android.md由 ehmo 的 MIT 许可项目platform-design-skills(Apple Human Interface Guidelines 与 Material Design 3 规则)蒸馏而来,并以 impeccable 的语气重写。

1.3 适用边界:哪些技术栈算“Android”

文档第一句就把覆盖范围写得很清楚:面向原生 Android 应用,具体包括 Jetpack Compose、Android Views(传统 View 体系)、React Native、Expo、Flutter——即凡是“最终运送到 Android 硬件上”的界面。这里的关键限定是“原生”二字:如果是纯浏览器里跑的移动端 Web 页面,它走的是 web 平台的通用规则,而不是这套 Material 守则;同样,CLAUDE.md 说明 live 模式、detectCLI 与设计钩子全部是 web-only 工具,对任何原生(ios/android/adaptive)项目都会被路由跳过。

1.4 每条规则都带可寻址的规则 ID

值得注意的一个仓库细节是:skill/reference/android.md里每条规范行末都带<!-- rule:android-* -->形式的 HTML 注释,例如rule:android-layout-adaptive-navrule:android-touch-target-48dprule:android-color-dynamic-colorrule:android-verify-emulator-capture等。这些稳定的规则标识让指南中的每一条都能被工具链精确定位、被测试与钩子引用,而不是只靠自然语言匹配。

二、原生模式的表达边界:品牌只能借 Material 的壳表达

文档给出一句贯穿全文的原则性陈述:

On native, the visitor mode narrows what expression may override. Material Design 3 governs structure, navigation, and interaction in every mode; brand expresses through Material's theming (color roles, type scale, shape, motion).

翻译成设计语言就是:在原生平台,无论你的模式是 Persuade(转化页)、Operate(工具型 App)还是 Read(文档型内容),Material Design 3 都接管结构、导航与交互;品牌只能通过 Material 的换肤系统来表达——即色彩角色(color roles)、字体字号阶梯(type scale)、形状(shape)与动效(motion)。这等同于宣告:结构层不可自创,表达层才是品牌发挥的空间。

同时文档保留了一条“平台债务”提醒:一个 Material-everywhere 的跨平台应用哪怕也装到了 iPhone 上,只要跑到 iOS 硬件上,就仍然欠 iOS 那套操作系统级保障——安全区 inset、Reduce Motion、边缘右滑返回。这正是 adaptive 平台值要求“两端参考文件都加载”的原因。

三、The Android slop test:一眼识破“穿 Android 皮的 iOS 应用”

这是 Android 平台上最核心的验收提问:

Would a fluent Android user trust this app, or trip on off-spec components?

一个资深的 Android 用户能否信任这款应用,还是会被不合规格的组件绊倒?文档指出最常见的破绽恰恰是“穿了 Android 皮的 iOS 应用”,典型症状包括:

  • 照抄 iPhone 的纯底部导航:iOS 的 Tab Bar 习惯被直接搬成唯一的底部导航条;
  • 无视系统 Back 手势的返回箭头:界面里画一个自造的返回箭头,却让系统级预测性返回(predictive Back)失效或冲突;
  • Cupertino 造型的开关与对话框:开关、弹窗沿用 iOS 的圆润形态(iOS 风格 switch、alert 样式)而没有 Material 化。

结论只有一句话:Material 3 就是规则书(rulebook)。要用它的组件,再通过它的主题机制把品牌织进去,而不是绕过组件另起炉灶。

四、Layout & structure:布局与结构四原则

文档的布局与结构部分给出四条硬性要求,每条都可落到 Material 3 的标准组件名上。

4.1 Material 导航必须匹配屏幕宽度(rule:android-layout-adaptive-nav)

  • 紧凑宽度(compact width,手机竖屏):使用底部导航条(Material 3 的 NavigationBar),承载 3–5 个目的地(destination);
  • 扩展宽度(expanded width,平板/大屏):切换为导航抽屉栏(NavigationRail)或抽屉(NavigationDrawer)。

最不能容忍的行为是“把一个手机底部导航条原封不动搬到平板上”(never ship a phone bottom-bar untouched on a tablet)。平板横向空间充裕,底部栏会浪费大量可读宽度,且不符合 Material 的响应式导航规范。

4.2 系统返回永远可用(rule:android-layout-system-back)

必须响应 Android 的**预测性返回手势(predictive Back gesture)**与 Back 键;永远不要困住用户,也不要劫持该手势(例如把 Back 手势改造成收起键盘之外的其他自定义语义而拦截系统返回)。从 Android 13 起的预测性返回还要求应用预览即将返回的目标界面,这更意味着返回栈必须交给系统管理。

4.3 真正 edge-to-edge:处理全部窗口 inset(rule:android-layout-window-insets)

内容要延伸到屏幕边缘,但必须正确应用以下 inset,避免内容被遮挡:

  • 状态栏(status bar)inset
  • 导航栏(navigation bar)inset
  • 刘海/挖孔(display cutout)inset
  • 输入法(IME)inset——软键盘弹出时输入框不能被键盘盖住。

在 Compose 中这对应WindowInsets体系(statusBarsnavigationBarsdisplayCutoutime)与Modifier.windowInsetsPadding(...);在传统 View 体系则对应setOnApplyWindowInsetsListener/WindowInsetsCompat。用对了 insets,深色沉浸式底栏、全面屏手势条与键盘弹起才不会“吃”掉内容。

4.4 顶部应用栏提供屏幕语境,单一主操作配 FAB(rule:android-layout-top-app-bar)

每个屏幕用 Top App Bar 说明“我在哪”(screen context);当该屏幕存在唯一的主操作时,用一个 FAB(Floating Action Button)与之配对。没有主操作就不要硬塞 FAB。

五、Touch targets:48×48 dp 的触控底线

48×48 dp minimumfor every touch target, with at least 8 dp between them.

文档规定:每一个触控目标最小 48×48 dp,相邻目标之间至少留8 dp间距。这是 Material 无障碍规范的核心数字(接近 44pt 的 iOS 对应值,但更大),直接决定拇指能否可靠点中目标、以及误触概率。值得注意的是 48 dp 是“可点击热区”而非视觉尺寸,实践中常通过扩大可点击区域实现视觉更紧凑、热区仍达标的布局;8 dp 间距则是防误触的间隔底线。这条对应的规则 ID 是rule:android-touch-target-48dp,也是审计时会真实检查的硬指标。

六、Typography:交给 Material 字体阶梯,字号只用 sp

6.1 用 Material type scale 映射文本角色(rule:android-typo-type-scale)

文本必须映射到 Material 的字体角色阶梯:

  • Display(大标题展示,仅用于品牌化首页大字号场景)
  • Headline(屏级标题)
  • Title(区块与列表标题)
  • Body(正文)
  • Label(控件内文字、说明文字)

以上每个角色又分 large / medium / small 三档。规则是“给文本先定角色、再从阶梯取样式”,绝不允许在具体屏幕上逐个手选字号(never hand-pick sizes per screen)。手选字号的直接后果就是字号体系失序、层级混乱。

6.2 系统字体是 Roboto,品牌字体经由阶梯注入(rule:android-typo-system-font)

Roboto 是 Android 的系统字体。如果要引入品牌字体,正确的做法是把它作为阶梯的替换字体通过主题注入(Compose 中即定义Typography并把品牌 face 挂到各角色上),并保证正文、标签与控件仍然清晰、一致。而不是在个别组件里混用字体制造割裂。

6.3 只用 sp,绝不用固定 px(rule:android-typo-scalable-sp)

字号必须使用sp(scaled pixels)单位,让文字跟随系统字体缩放设置。用户把系统字体调大,界面文字随之放大;若用 dp 或 px 写死字号,就会在辅助功能字体缩放下出现截断或错位。这也是后文“验收”环节要专门检查 font scale 的原因。

七、Color & theming:用角色令牌换肤,不用裸 hex

7.1 Material 色彩角色是唯一合法的取色方式(rule:android-color-role-tokens)

文档给出必须使用的 Material 色彩角色清单:primaryon-primarysurfacesurface-variantsecondary-containeroutlineerror。要点在于:

Role tokens resolve light/dark and contrast variants automatically; raw hex breaks there.

角色令牌会自动解析浅色/深色/高对比度下的正确取值;直接写死的裸十六进制颜色在这些变体里必然失效。主题换肤、深色模式、无障碍对比度增强,全靠“代码只引用角色、角色解析最终色值”这一层抽象才能自动工作。

7.2 Dynamic Color(Material You)按需启用(rule:android-color-dynamic-color)

在合适的场景使用动态取色:Android 12+ 上从用户壁纸派生整个配色方案(scheme),同时必须准备一个静态配色作为回退(static fallback)——因为不是所有设备、所有 Android 12+ 版本都支持动态取色,品牌化程度高的界面也应保守使用。

7.3 深色主题是一等公民,不是快速反相(rule:android-color-dark-theme)

深色主题必须被设计并测试为一套正式的方案,绝不允许一键“quick invert”(把颜色粗暴反相)。正确做法仍是通过角色令牌自动解析深色变体,并在深色下人工校准表面色、文字对比与图形化强调。

7.4 色调化层级表达高度(rule:android-color-tonal-elevation)

用 Material 标准的 **surface 色调层级(tonal elevation)**来传达“抬升感”,必要时才叠加阴影;禁止随手加任意 drop shadow。也就是说,卡片浮起的高度变化应当体现在 surface 色彩的明暗层级上,而不是靠自定义投影。

八、Components & motion:原生组件 + 单 FAB + Material 动效

8.1 只用 Material 组件,禁止移植 iOS 控件(rule:android-components-material)

文档列出的合法组件集合:

  • Buttons:filled(实心)/ tonal(色调)/ outlined(描边)/ text(文字)四种样式;
  • FAB(浮动操作按钮);
  • Switches(开关)、chips(筛选/输入片)、snackbarsbottom sheetsMaterial dialogs(Material 风格对话框);
  • Navigation bar / rail / drawer(底部导航条/侧栏/抽屉)。

硬性禁令是:绝不移植 iOS 控件,也绝不自行发明等价物(never port iOS controls or invent equivalents)。iOS 的 switch、alert、tab bar 造型出现在 Android 应用里,就是上文 slop test 中“Cupertino 形状开关和对话框”的直接扣分项。

8.2 一个 FAB 只能对应一个主操作(rule:android-components-single-fab)

永远只放一个FAB,且它只服务屏幕的主操作。禁止堆叠多个 FAB,也禁止把 FAB 浪费在次要任务上。

8.3 瞬时反馈用 Snackbar,打断性决策才用 Dialog(rule:android-components-snackbar)

  • Snackbar:承载转瞬即逝的反馈(操作成功、已删除等),可含“撤销/重试”类操作,但不要用 Toast 承担这个职责
  • Dialog:只用于必须打断用户的决策(破坏性确认、需要立即表态的选择)。

这个区分对应 Android 的模态层级:常规反馈走轻量 Snackbar,真正需要用户停下做决定才提升到模态对话框。

8.4 Material 动效模式,并尊重系统“移除动画”设置(rule:android-motion-material-and-reduce)

动效必须遵循 Material 的三种过渡模式:

  • Container transform(容器变换:元素在两种形态间以同一容器形变过渡);
  • Shared-axis(共享轴:父子页面沿同一轴滑动);
  • Fade-through(淡入贯穿:层级切换时淡出淡入)。

并统一使用 Material 标准缓动曲线与时长。同时必须响应系统的Remove animations(移除动画)无障碍设置——检测到该设置开启时,用交叉淡入(crossfade)或直接硬切(instant cut)代替大段位移动效。

九、Verifying the build:用 adb 完成交付前验收

这是文档中实操性最强的一节,也是 native 平台与 web 平台验收方式的分水岭:原生截图必须来自模拟器或真机,绝不来自浏览器。因为 impeccable 的 finish reviewer 等工作流依赖真实设备截图来评估还原度,浏览器渲染无法代表 Android 的渲染管线。

9.1 截图:构建安装后用 screencap 采集

流程是:先完成构建并安装到目标,再执行:

adb exec-out screencap -p > <path>

同时连接了多台设备时,必须用-s <serial>指定目标设备:

adb -s <serial> exec-out screencap -p > <path>

截图覆盖范围必须与 App 实际交付的设备形态一致:至少一台手机;如果平板是交付目标,则至少再补一台平板。截图文件要写入评审流程(review flow)约定的位置——按 plugin/agents/impeccable-finish-reviewer.md 的约定,原生平台的评审截图放在.impeccable/review/,且使用设备形态命名(如phone.pngtablet.png;adaptive 平台再按 OS 加后缀),这与 web 平台的desktop.png/mobile.png命名约定不同。

9.2 深色主题与字体缩放必须进入验收流程

两件最容易掩盖布局问题的状态必须纳入截图清单:

切换深色主题:

adb shell cmd uimode night yes

放大字体到 1.3 倍,检查是否有标签被截断(固定布局最容易暴露此问题):

adb shell settings put system font_scale 1.3

验收结束后恢复默认字体缩放:

adb shell settings put system font_scale 1.0

当多台目标设备同时连接时,上述命令同样要加上捕获用的-s <serial>

adb -s <serial> shell cmd uimode night yes adb -s <serial> shell settings put system font_scale 1.3

font_scale 1.3正是对前文“sp 单位、绝不用 px”规则的实证:字号真的跟随系统设置放大后,凡是写死尺寸的标签、按钮就会原形毕露。

9.3 证据来源要诚实:模拟器管广度,真机管手感

文档最后一条验收纪律是:

Emulators give breadth; gestures, refresh rates, and performance need hardware. Say which one produced the evidence.

  • 模拟器(emulator)的价值是“广度”:快速覆盖多机型、多系统版本、多屏幕形态;
  • 真机的价值是“手感”:返回手势、刷新率表现、真实性能只能靠硬件验证;
  • 产出证据时必须说明截图来自模拟器还是真机(say which one produced the evidence),不冒充、不混用。这条规则 ID 为rule:android-verify-hardware-honesty,也是一条诚信要求:评审方必须知道证据的生成环境才能判断其可信度。

十、这些守则如何融入 impeccable 的完整工作流

android.md不是孤立文档,仓库里有多个命令与代理会引用它的内容,理解这条引用网络有助于在实际使用时“对号入座”:

  • 原生代码级审计:当平台为原生时,audit命令走 plugin/skills/impeccable/reference/audit.native.md——这是直接从源码(SwiftUI / UIKit / Compose / React Native / Flutter)打的代码级审计,不适用浏览器工具;评分标准即 ios.md / android.md(adaptive 两端都读),并要求在评分前先读完平台参考文档。
  • 原生适配adapt命令的原生变体 plugin/skills/impeccable/reference/adapt.native.md 明确警告“把适配当成缩放是陷阱”,跨设备形态、方向或平台的迁移必须在目标平台文档的惯例内重新思考体验。
  • 动效/排版/布局命令animatetypesetlayout的参考文档各自声明“原生场景请遵循平台文档的 Motion / 排版 / 布局与无障碍缩放章节”,不套用 web 工具链。
  • 完工评审:评审代理 plugin/agents/impeccable-finish-reviewer.md 接收父流程截图(原生平台即phone.png/tablet.png等),结合方向契约与 PRODUCT.md 做最终的 fidelity 复核。
  • 原生项目的工具豁免:live 变体模式、detect检测 CLI 与设计钩子都是 web-only;当 PRODUCT.md 声明原生平台时,钩子会跳过对.tsx/.ts/.js文件的扫描(因为 React Native 项目恰恰就是由这些文件构成的,按 web 规则扫描会产生误报)。

结语:用一份守则回答“Android 用户会信任它吗”

回到文档开头那个问题:一个熟练的 Android 用户会不会信任这款应用?android.md给出的答案路径是清晰的——结构上,导航匹配屏幕宽度、系统 Back 永远可用、edge-to-edge 正确处理 insets、顶栏+FAB 给出语境;规格上,48×48 dp 触控、sp 字号、Material 角色令牌、一等公民的深色主题、单一 FAB 的组件纪律;动效上,容器变换/共享轴/淡入贯穿,并尊重系统移除动画设置;而这一切最终都要靠模拟器与真机上的adb截图验收来落地。配合adb shell cmd uimode nightadb shell settings put system font_scale这两组开关,把深色模式与字体缩放真正跑进截图里,再诚实标注证据来源,一套可靠的 Android 交付验收闭环就成立了。

对使用者而言,这份文档最大的价值在于:它把“Material 3 蒸馏规则”压缩成了一张可直接对照的检查表;而对阅读仓库的人来说,skill/reference/android.md 中逐条规则携带的rule:android-*标识,也为将来把每条规范接入自动化检查提供了天然的锚点。

【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccable

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询