蓝湖稿还原最容易陷入的误区,是把验收简化成截图比对:看起来差不多,就认为实现正确。

这套方法的问题不在于截图没用,而在于截图只能暴露现象,不能解释原因。一个 12dp 的间距看起来偏大,原因可能不是某个 margin 写错,而是子控件底距、列表 padding、模块 margin、Provider spacer 叠在了一起。一个颜色看起来接近,可能只是当前皮肤下的十六进制值相同,Design Token 的语义已经错了。一个长列表截图正常,短内容或空列表时才会露出错误的页面底色。

所以,蓝湖验收要想交给 AI 稳定执行,关键不是让 AI「看得更像人」,而是把「像不像」拆成可计算、可追溯、可复查的工程证据。


截图只能回答「像不像」

UI 还原的误差,很多时候不是属性值错,而是属性归属错。

例如,设计稿要求顶部 Tab 到首个内容模块是 8dp。代码里可能有多种实现:

  • Tab 自身有 bottom padding。
  • 页面根布局放了一个 8dp Spacer。
  • 首个模块设置了 layout_marginTop=8dp
  • 列表 Header 或 Provider 插入了间距。

截图上都可能是 8dp。但后续只要隐藏某个模块、切换 Tab、内容不足一屏,真正承担间距的那一层就会影响页面表现。

背景也是同样的问题。页面底色可能来自 Activity 根、Fragment 根、Tab 容器、刷新容器、RecyclerView 父容器或 Item 根节点。长列表填满屏幕时,错误背景被卡片盖住;短内容、空列表、加载态或 overscroll 时,底色问题才会出现。

这就是截图比对的边界:它能指出「这里不对」,但无法稳定回答「是哪一层不对」。


结构化数据才是验收规格

蓝湖返回的 HTMLCSStokenslayoutlayers,比截图更适合作为 AI 审核输入。截图是结果,结构化数据是规格。

把这些数据交给 AI 之前,需要先把问题拆成几类:

  • 页面结构:根容器宽度、模块边界、卡片尺寸、圆角、背景。
  • 间距来源:模块之间的距离由谁提供,是上一个模块、下一个模块、列表容器,还是 Provider。
  • 背景归属:从窗口根到 Item 根,每一层的背景是否正确。
  • 颜色语义:标题、正文、元信息、禁用态、右侧操作文字、操作箭头分别对应什么 Token。
  • 结构元素:标题左图标、右侧箭头、角标、标签、分割线是否应该存在。
  • 运行态:数据绑定、图片加载器、圆角裁剪、字体覆盖和空状态是否改变最终表现。

这时 AI 才能从「看图找不同」进入「代码级审核」。它不只是判断视觉差异,而是能说清楚差异属于哪一层、哪一个资源、哪一段运行逻辑。


间距要算最终可见距离

间距问题最容易反复返工。原因是很多人会把蓝湖上的 12dp 理解成「找一个 margin 改成 12dp」。

实际要看的不是某一个 XML 值,而是两个视觉锚点之间的最终可见距离。

比如蓝湖标注的是「上一张卡片最后一个标签」到「下一个模块标题」之间 12dp,代码里可能同时存在:

  • 标签自身的 layout_marginBottom=12dp
  • 横向列表的 paddingBottom=12dp
  • 模块根节点的 layout_marginBottom=12dp

渲染出来不是 12dp,而是 12 + 12 + 12 = 36dp。这种问题靠截图能看出「偏大」,但不能直接得出修复方案。正确做法是先写出可见间距栈,再决定保留哪一层、删除哪一层。

一个可复查的间距记录至少应该长这样:

视觉关系 蓝湖值 当前来源 当前可见距离 处理
标签底部 -> 下个模块标题 12dp 标签底距 12dp + 列表底部 12dp + 模块底距 12dp 36dp 保留标签底距,删除重复容器留白

这类台账应该先于内部元素微调。否则很容易出现「图标和文字都改准了,但模块之间仍然不对」。


背景归属:底色不是列表项属性

新版蓝湖验收流程中,背景和底色需要作为一等检查对象处理。页面底色并不总是由当前可见的卡片或列表项决定,真正需要审查的是从外到内的背景归属链。

典型背景归属链如下:

Activity/window root
-> Fragment/page root
-> Tab/page container
-> refresh/layout parent
-> RecyclerView/ListView/ScrollView
-> item/module root

每一层都需要记录三件事:是否显式设置背景、透明时继承哪一层颜色、最终暴露给用户的颜色是什么。尤其在 Android 列表页中,RecyclerView 通常应保持透明,页面底色由父容器或页面根节点承担;卡片和模块背景则属于 Item 或模块根节点。把页面底色直接涂到列表控件上,可能掩盖短内容和空状态问题,也可能破坏同一页面内不同 Tab 的背景语义。

底部空白区域是最容易漏掉的检查点。短内容、空列表、加载态、模块隐藏、最后一个 Item 下方 padding、列表 overscroll,都可能暴露真实页面背景。只验证长列表满屏状态,不能证明页面底色正确。


颜色不能只看十六进制

颜色问题也不能只看十六进制值。

蓝湖如果给出的是命名 Token,就要按 Token 语义找项目里的资源。两个资源在当前皮肤下可能都是同一个颜色,但一个是「卡片背景」,另一个是旧版近似色。当前截图相同,不代表深色模式、皮肤切换或后续设计迭代下仍然正确。

同一行里的颜色还要按角色拆开。模块 Header 里,标题、右侧操作文字、操作箭头和分割线可能在同一个布局文件中,但它们不是同一个语义角色。修复右侧操作颜色时,不能顺手改标题;修复箭头 tint 时,也不能把正文、元信息或禁用态文字一起替换。

因此,颜色审核表需要额外记录两列:

视图身份 语义角色 蓝湖 Token 或颜色 当前代码 修复边界
tv_title 模块标题 主文本 Token 主文本资源 保持
tv_more 右侧操作文字 次级文本 Token 主文本资源 只改操作文字
drawableRight 右侧操作箭头 次级图标 Token 主文本资源 与操作文字一起改

同类组件也只能比较同一角色。一个模块标题色正确,不能证明右侧操作色也正确。若蓝湖只返回原始颜色值,也应先查项目资源或生成后的 merged resources,确认它对应哪个语义资源,再决定是否修改代码。


运行态验证:跨越静态代码的边界

Android 的 XML、Flutter 的 Widget 树或 HarmonyOS 的 ArkUI 声明只能反映静态结构。界面的最终呈现还会受到数据绑定、运行时样式覆盖以及视图隐藏状态的改变。

利用 AI 辅助审核时,可以将验收范围延展至运行态:

  • 数据绑定追踪:让 AI 顺着 ViewModel 或 Controller 的执行路径,检查运行时是否会动态追加前缀、后缀或空状态占位文案。
  • 动态修饰符:检查字重属性是否在代码中被 setTypeface 或 ArkUI 的修饰符错误覆盖。
  • 列表间距溯源:在 RecyclerView 或 Flutter ListView 中,项间距可能由 Item 根布局、ItemDecoration 或分割线机制共同作用。AI 能够跨文件检索相关的 Provider 模型与装饰器代码,避免人工审核极易漏掉的间距生成源。
  • 空白态背景追踪:列表内容不足一屏时,最终可见背景来自父容器、刷新布局还是列表控件本身,需要沿布局绑定、适配器和容器层级追到运行态。
  • 运行态图片追踪:服务端下发图标或缩略图时,要顺着布局 ImageView、Adapter 绑定、图片加载器和占位图查到最终调用。父容器有圆角并不代表图片本体有圆角,除非父容器真实裁剪子元素,或加载器应用了圆角变换。

结构元素:先查存在,再查样式

视觉走查常把标题左图标、右侧箭头、清除按钮、角标、标签和分割线当成「装饰」。在自动化验收中,这些元素需要单独检查。第一步不是判断大小和颜色,而是确认它们是否存在于蓝湖图层。

典型漏检包括:

  • 设计稿中的标题行已经只有文字,代码仍保留旧版标题左侧热度图标。
  • 右侧操作文案、箭头或清除按钮在某个状态下多出或缺失。
  • 卡片内部的排名角标、NEW 标识、状态标签、股票标签被误认为顶部 Tab 或筛选标签。
  • 服务端图标只核对了 XML 宽高,没有核对加载器是否处理圆角、裁剪和占位图。

因此,AI 审核需要把标题行结构和卡片内部结构拆开。标题左图标、右侧操作、箭头、分割线属于模块 Header 层;排名角标、角落丝带、状态胶囊、覆盖标签属于 Item 或卡片层。若用户只说「标签」,审核流程也应先定位具体图层或代码控件,再决定它是 Tab、筛选项、角标还是卡片内状态标签。


修复后先读 diff

AI 自动修复视觉问题时,风险不只在于改错值,还在于改得过宽。颜色资源尤其容易出现这种问题:同一个旧资源名可能同时用于标题、正文、右侧操作和箭头。一次全局替换可以通过编译,却把原本正确的相邻角色一起改掉。

间距修复也类似。蓝湖标注 12dp,不等于直接把某个 layout_marginBottompaddingBottom 改成 12dp。若当前可见间距过大,原因往往是多个层级重复提供了同一段空间。此时应先移除重复层,而不是新增或移动另一个外边距。

所以自动修复前,应先写清楚目标:

  • 文件路径。
  • 视图 ID 或绑定名。
  • 属性名。
  • 旧资源或旧值。
  • 新资源或新值。
  • 语义角色。
  • 可见间距栈中的当前层级贡献值。

补丁后先读 diff,再运行构建。diff 至少要证明:只改了目标角色;同一行中的标题、正文、元信息没有被误改;成对元素已经一起处理,例如右侧操作文字与右侧操作箭头;间距修复只删除或调整了可见间距栈中被判定为重复的那一层。

如果 diff 显示修复右侧操作颜色时顺带改了模块标题,审核还没有完成。此时应先回退误改部分,再继续验证。


一套更适合落地的流程

把上面的要求整理成流程,其实不复杂:

  1. 先确定页面、状态、主题、Tab 和蓝湖节点。
  2. 读取蓝湖的结构化规格,而不是只拿截图。
  3. 自顶向下建立页面盒模型,先看根容器、模块边界、背景归属。
  4. 对相邻模块写间距台账,尤其记录最终可见间距栈。
  5. 按语义角色检查颜色,不按同一行或同一个旧资源名批量替换。
  6. 单独检查结构元素是否存在,包括标题左图标、右侧箭头、角标、标签和分割线。
  7. 追到运行态,确认数据绑定、图片加载器、字体覆盖和列表 Provider 没有改变最终表现。
  8. 修改后先读 diff,再构建或截图验证。

不同平台只是在单位和控件能力上有差异。Android View/XML 主要看 dpsp、约束关系、includeFontPadding、Typeface、RecyclerView 背景和 Provider;Flutter 主要看 EdgeInsetsSizedBoxTextStyleFontWeight;HarmonyOS ArkUI 主要看 vpfp.margin.padding 和父布局约束。


总结

让 AI 参与蓝湖验收,不是把截图丢给模型,让它替人工看一遍。真正有价值的是把设计稿拆成结构化规格,再让 AI 沿代码实现逐层核对。

可靠的 UI 审核至少要回答四个问题:

  • 设计值是什么。
  • 当前代码由哪一层实现。
  • 最终渲染为什么会偏差。
  • 补丁是否只改了目标层级。

截图仍然需要看,但它应该用于验证结果,而不是充当全部验收依据。真正能减少返工的,是页面级盒模型、可见间距栈、背景归属链、颜色语义角色和运行态追踪这些可复查的工程证据。