MasterGo + Claude Code 生成 Android 布局:完整实践指南

<h1>MasterGo + Claude Code 生成 Android 布局:完整实践指南</h1>
<p>用 Claude Code 把 MasterGo 设计稿转成 Android 布局,我前几次得到的结果都不太能看:列表被生成了一坨静态重复布局,XML 里硬编码着 <code>android:text="张三"</code>,多样式的信息流只认出一种 item——每次改生成结果,花的时间比自己手写布局还多。</p>
<p>坑踩得多了才意识到,这些问题不是随机的。根因在于设计稿是静态视觉快照,AI 没法从稿子里猜出列表语义和动态数据。逐个案例去修补不可持续,得把规则前置:设计侧的命名规范、截图与 DSL 的阅读顺序、写进 CLAUDE.md 和 Skill 的生成与自检规则。</p>
<p>这篇文章把这套体系完整整理出来:基础问题覆盖边界识别和动态数据,进阶问题覆盖多 ViewType、嵌套 RV 与截图和 DSL 的阅读顺序。文中的命名规范、Prompt 模板、Skill 文件都可以直接拿去用。</p>



<h2>一、问题根因总览</h2>
<p>所有问题的本质是同一个矛盾:<strong>MasterGo 设计稿是“静态视觉快照”,而 Android 布局是“动态语义结构”</strong>。</p>
<table>
<thead>
<tr>
<th>问题类别</th>
<th>具体表现</th>
<th>根因</th>
</tr>
</thead>
<tbody><tr>
<td>RV 边界识别不准</td>
<td>把列表生成为静态重复布局,或漏掉滚动区域</td>
<td>设计稿只画了3~5条item,AI无法判断“这是列表还是固定布局”</td>
</tr>
<tr>
<td>动态数据丢失</td>
<td>XML中硬编码 <code>android:text="张三"</code></td>
<td>设计稿文字/图片全是占位符,AI默认照抄</td>
</tr>
<tr>
<td>多ViewType遗漏</td>
<td>只识别出一种item样式,其余被忽略或误判为独立区块</td>
<td>同一列表中不同样式的item在设计稿中视觉差异大,AI未关联</td>
</tr>
<tr>
<td>嵌套RV展平</td>
<td>内层横向列表被当成外层一部分,或变成静态LinearLayout</td>
<td>AI未理解“item内部还包含可滚动容器”的层级语义</td>
</tr>
<tr>
<td>DSL与截图矛盾</td>
<td>生成的结构与视觉不符</td>
<td>单一输入源信息不完整,缺少交叉验证机制</td>
</tr>
</tbody></table>


<h2>二、核心解法体系(四层防线)</h2>
<h3>第一层:设计侧命名规范(成本最低、收益最高)</h3>
<p>在 MasterGo 中建立统一的语义化命名体系,让 MCP 导出的 DSL 自带结构信息:</p>
<pre><code>✅ 推荐命名体系:

[RV/Outer] 首页信息流 → 外层纵向RecyclerView
├─ [RV-Item/Banner] 横幅卡片 → ViewType: BANNER
├─ [RV-Item/Product] 商品卡片 → ViewType: PRODUCT
├─ [RV-Item/Ad] 广告卡片 → ViewType: AD
├─ [RV-Item/Recommend] 推荐容器
│ └─ [RV/Inner] 横向推荐列表 → 嵌套横向RecyclerView
│ ├─ [RV-Item] 推荐卡片A
│ ├─ [RV-Item] 推荐卡片B
│ └─ [RV-Item] 推荐卡片C
└─ [RV-Item/Section] 分组标题 → ViewType: SECTION

[Fixed] 顶部搜索栏 → 固定Header,不随列表滚动
[Fixed] 底部TabBar → 固定Footer
</code></pre>
<p><strong>命名规则速查:</strong></p>
<table>
<thead>
<tr>
<th>前缀</th>
<th>含义</th>
<th>示例</th>
</tr>
</thead>
<tbody><tr>
<td><code>[RV/Outer]</code></td>
<td>外层RecyclerView</td>
<td><code>[RV/Outer] 商品列表</code></td>
</tr>
<tr>
<td><code>[RV/Inner]</code></td>
<td>嵌套RecyclerView</td>
<td><code>[RV/Inner] 横向推荐</code></td>
</tr>
<tr>
<td><code>[RV-Item]</code></td>
<td>单类型item</td>
<td><code>[RV-Item] 商品卡片</code></td>
</tr>
<tr>
<td><code>[RV-Item/变体名]</code></td>
<td>多ViewType item</td>
<td><code>[RV-Item/Banner]</code></td>
</tr>
<tr>
<td><code>[Fixed]</code></td>
<td>固定区域</td>
<td><code>[Fixed] 底部导航</code></td>
</tr>
<tr>
<td><code>[Scroll]</code></td>
<td>ScrollView(非列表)</td>
<td><code>[Scroll] 协议文本</code></td>
</tr>
</tbody></table>
<blockquote>
<p>设计师花5分钟做好命名,开发侧能省2小时调试。MasterGo MCP导出的DSL会完整保留图层名,这是最可靠的语义信号。</p>
</blockquote>



<h3>第二层:截图与DSL的双通道阅读策略(关键流程)</h3>
<h4>核心原则:先截图(宏观语义)→ 再DSL(微观精确)→ 最后交叉验证</h4>
<pre><code>┌──────────────────────────────────────────────────────┐
│ 双通道阅读流程 │
│ │
│ Phase 1: 截图 → 宏观语义判断 │
│ ┌────────────────────────────────────────────────┐ │
│ │ • 区域划分:哪些是固定/滚动/嵌套 │ │
│ │ • 滚动判断:被屏幕边缘截断 → 可滚动 │ │
│ │ • 重复模式:视觉上重复的卡片 → 列表语义 │ │
│ │ • 嵌套检测:item内部有横向排列子元素 → 嵌套RV │ │
│ │ • 多类型:同一区域卡片结构明显不同 → 多ViewType │ │
│ │ │ │
│ │ 输出:结构分析表 │ │
│ │ ⏸️ 暂停,等用户确认 │ │
│ └──────────────────────┬─────────────────────────┘ │
│ ▼ │
│ Phase 2: MCP DSL → 精确数值提取 │
│ ┌────────────────────────────────────────────────┐ │
│ │ • 精确尺寸/颜色/字体/间距 │ │
│ │ • 图层嵌套层级(父子关系) │ │
│ │ • Auto Layout方向和间距 │ │
│ │ • 与Phase 1结论交叉对比 │ │
│ │ │ │
│ │ 矛盾处理规则: │ │
│ │ • 截图显示滚动 + DSL未超出 → 仍按滚动处理 │ │
│ │ (设计稿可能只展示部分数据) │ │
│ │ • DSL中≥3个相同结构兄弟节点 → 强制识别为RV │ │
│ │ • DSL中节点被clip裁切 → 等同于"被截断" │ │
│ │ │ │
│ │ 输出:最终结构确认表 │ │
│ │ ⏸️ 暂停,等用户确认 │ │
│ └──────────────────────┬─────────────────────────┘ │
│ ▼ │
│ Phase 3: 代码生成(基于确认后的结构+DSL数据) │
└──────────────────────────────────────────────────────┘
</code></pre>
<h4>为什么这个顺序?</h4>
<table>
<thead>
<tr>
<th>能力维度</th>
<th>截图能做(DSL不能)</th>
<th>DSL能做(截图不能)</th>
</tr>
</thead>
<tbody><tr>
<td>滚动判断</td>
<td>✅ 内容被屏幕截断 → 可滚动</td>
<td>❌ 无法感知视觉裁切</td>
</tr>
<tr>
<td>重复语义</td>
<td>✅ 视觉上“看起来是一组”</td>
<td>❌ 只有节点树,无语义</td>
</tr>
<tr>
<td>整体层次</td>
<td>✅ 一眼看出固定/滚动/嵌套</td>
<td>❌ 需要逐层解析</td>
</tr>
<tr>
<td>精确数值</td>
<td>❌ 像素级估算误差大</td>
<td>✅ 精确px/hex/dp</td>
</tr>
<tr>
<td>图层关系</td>
<td>❌ 遮挡/分组难以判断</td>
<td>✅ 明确的父子嵌套</td>
</tr>
<tr>
<td>样式参数</td>
<td>❌ 圆角/阴影/字重难辨</td>
<td>✅ 完整样式属性</td>
</tr>
</tbody></table>
<blockquote>
<p>截图回答“是什么”(语义),DSL回答“是多少”(精确)。两者互补,不能互相替代。</p>
</blockquote>


<h3>第三层:四大问题的具体解法</h3>
<h4>问题1:RecyclerView 边界识别</h4>
<p><strong>识别规则(写入 CLAUDE.md / Skill):</strong></p>
<pre class="language-markdown"><code>## RecyclerView 边界判定规则

满足以下任一条件 → 生成 RecyclerView(而非静态布局):

  1. 同父容器下 ≥3 个结构完全相同的兄弟节点
  2. 图层名称包含 [RV]、list、recycler、列表、卡片流
  3. 内容被父容器 clip 裁切(DSL中overflow=hidden且子节点超出)
  4. 截图中内容被屏幕边缘截断

滚动方向判定:

  • 重复节点纵向排列 → LinearLayoutManager(VERTICAL)
  • 重复节点横向排列 → LinearLayoutManager(HORIZONTAL)
  • 重复节点网格排列 → GridLayoutManager(spanCount=N)
  • 截断在水平方向 → 横向
  • 截断在垂直方向 → 纵向
    </code></pre>
    <p><strong>Prompt 模板(Phase 1 截图分析时使用):</strong></p>
    <pre class="language-markdown"><code>请观察这张设计稿截图,完成以下分析(不写代码):
  1. 哪些区域的内容被屏幕边缘截断?→ 标记为可滚动,标注截断方向
  2. 哪些区域存在视觉上重复的卡片/行?→ 标记为列表
  3. 哪些元素始终可见(顶栏/底栏)?→ 标记为固定
  4. 某个重复单元内部是否还包含横向排列的子元素?→ 标记为嵌套RV

输出格式:
| 区域 | 类型(RV/Fixed/Scroll) | 滚动方向 | Item类型数 | 含嵌套RV | 备注 |
</code></pre>
<h4>问题2:动态数据绑定</h4>
<p><strong>XML规范(写入 CLAUDE.md):</strong></p>
<pre class="language-markdown"><code>## 动态数据绑定规范

  1. 所有运行时动态赋值的文本:
    ✅ tools:text="示例商品名称"
    ❌ android:text="张三"

  2. 所有运行时动态加载的图片:
    ✅ tools:src="@drawable/placeholder"
    ❌ android:src="@mipmap/avatar_zhangsan"

  3. 条件显示/隐藏的View:
    ✅ android:visibility="gone" + tools:visibility="visible"

  4. 每个需要数据绑定的View必须有明确id:
    ✅ android:id="@+id/tv_title"
    命名规范:类型前缀_语义名(tv_title, iv_avatar, rv_list, btn_submit)

  5. 提供数据模型时,字段与设计稿文本一一对应:

    { "title": "string, 最多2行", "price": "double, 显示为¥{price}" }
    

</code></pre>
<h4>问题3:多 ViewType RecyclerView</h4>
<p><strong>设计侧</strong>:用 <code>[RV-Item/变体名]</code> 命名区分不同类型</p>
<p><strong>Prompt 侧</strong>:附带 ViewType 映射表</p>
<pre class="language-markdown"><code>## 多ViewType声明

[RV/Outer] 首页信息流 → RecyclerView(VERTICAL)

ViewType 图层名 布局文件 数据模型 出现规律
TYPE_BANNER(0) [RV-Item/Banner] item_banner.xml BannerData 每10个出现1次
TYPE_PRODUCT(1) [RV-Item/Product] item_product.xml ProductData 主要数据
TYPE_AD(2) [RV-Item/Ad] item_ad.xml AdData 每5个插入1个
TYPE_SECTION(3) [RV-Item/Section] item_section.xml SectionData 分组时出现

</code></pre>
<p><strong>代码生成规范(写入 Skill):</strong></p>
<pre class="language-markdown"><code>## 多ViewType生成规范

数据层:sealed class 作为基类
sealed class FeedItem {
data class Banner(...) : FeedItem()
data class Product(...) : FeedItem()
...
}

Adapter:

  • 继承 ListAdapter<FeedItem, RecyclerView.ViewHolder>
  • getItemViewType(): when(item) 返回类型常量
  • onCreateViewHolder(): 按viewType inflate不同布局
  • onBindViewHolder(): when(holder) 分发绑定

DiffUtil:

  • areItemsTheSame: 按类型+id判断
  • areContentsTheSame: data class自动equals

自检:

  • when分支覆盖所有ViewType?
  • 每个ViewHolder只引用自己的ViewBinding?
  • DiffUtil能区分不同类型?
    </code></pre>
    <h4>问题4:嵌套 RecyclerView</h4>
    <p><strong>设计侧</strong>:<code>[RV-Item]</code> 内部嵌套 <code>[RV/Inner]</code></p>
    <p><strong>布局生成规范:</strong></p>
    <pre class="language-xml"><code>
    <LinearLayout orientation="vertical">
    <TextView android:id="@+id/tv_section_title"
    tools:text="猜你喜欢" />
    <androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rv_inner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:layoutManager="LinearLayoutManager"
    tools:orientation="horizontal"
    tools:listitem="@layout/item_recommend_card" />
    </LinearLayout>
    </code></pre>
    <p><strong>Kotlin生成规范(写入 Skill):</strong></p>
    <pre class="language-markdown"><code>## 嵌套RV生成规范

外层Adapter的对应ViewHolder中:
class RecommendRowHolder(binding: ItemRecommendRowBinding)
: RecyclerView.ViewHolder(binding.root) {
private val innerAdapter = RecommendCardAdapter()
init {
binding.rvInner.apply {
layoutManager = LinearLayoutManager(context, HORIZONTAL, false)
adapter = innerAdapter
setHasFixedSize(true)
isNestedScrollingEnabled = false
}
}
fun bind(data: RecommendRowData) {
binding.tvSectionTitle.text = data.title
innerAdapter.submitList(data.cards)
}
}

性能优化(必须生成):

  • 多个内层RV使用相同item类型 → 共享RecycledViewPool
  • 内层RV设置 isNestedScrollingEnabled = false
  • 嵌套深度限制:最多3层,超过提醒用户简化
    </code></pre>


    <h3>第四层:Claude Code Skills 工程化</h3>
    <h4>① 项目级 <code>CLAUDE.md</code>(必做)</h4>
    <pre class="language-markdown"><code># CLAUDE.md

项目信息

  • 语言:Kotlin
  • 布局:XML + ViewBinding
  • 图片加载:Glide
  • 列表:RecyclerView + ListAdapter + DiffUtil

MasterGo 转码规则

  1. 优先使用 MCP DSL,截图作为语义补充
  2. 阅读顺序:截图(宏观) → DSL(精确) → 交叉验证
  3. ≥3个相同结构兄弟节点 → RecyclerView
  4. 被clip裁切/屏幕截断 → 可滚动
  5. [RV-Item/变体名] → 多ViewType
  6. [RV-Item]内含[RV/Inner] → 嵌套RV
  7. 动态文本一律用 tools:text,禁止硬编码
  8. 尺寸换算:设计稿375px宽 → 360dp
  9. 颜色提取到colors.xml,不内联
  10. 输出路径:以用户输入的地址为准,不自行推断落盘位置

生成顺序(每步暂停确认)

结构分析 → XML布局 → 数据模型 → Adapter → 页面初始化 → 自检
</code></pre>
<h4>② 输出路径规则(补充)</h4>
<p><strong>生成文件落盘位置:以用户输入的地址为准。</strong></p>
<pre class="language-markdown"><code>## 输出路径规则

优先级(从高到低):

  1. 用户明确指定的路径(命令参数 / 对话中给出)→ 严格使用,不改动
  2. 用户未指定时 → 先询问用户,确认后再生成,不自行选择默认目录

落盘结构:

  • 单平台:直接在用户指定路径下生成标准 res/ 结构
    <用户路径>/res/layout/ 页面 + item 布局
    <用户路径>/res/drawable/ shape 背景
    <用户路径>/res/raw/ SVG 图标
    <用户路径>/res/values/ colors.xml / dimens.xml / strings.xml
  • 多平台:在用户指定路径下先建平台文件夹(android/、ios/ …),
    各平台产物放入对应文件夹

禁止行为:

  • 禁止把文件写到用户未确认的位置
  • 禁止生成后不告知最终落盘路径
  • 生成完成后必须输出:本次写入的完整目录路径 + 文件清单
    </code></pre>
    <blockquote>
    <p>原因:布局产物最终要并入 Android 工程的 <code>app/src/main/res/</code>,
    落盘位置不对会造成“生成了但找不到”的问题。以用户输入为唯一事实来源,
    生成完毕必须回显完整路径供用户确认。</p>
    </blockquote>
    <h4>③ 完整 Skill 文件</h4>
    <p><code>.claude/skills/design-to-android/SKILL.md</code>:</p>
    <pre class="language-markdown"><code>---
    name: design-to-android
    description: |
    将 MasterGo 设计稿转换为 Android XML + Kotlin 代码。
    支持:多ViewType、嵌套RecyclerView、动态数据绑定。
    当用户提供设计稿链接或截图并要求生成Android布局时触发。

MasterGo → Android 布局转换

前置条件

  • MasterGo MCP 已配置
  • 用户提供:设计稿链接(带layerId)+ 可选截图

执行流程

Phase 1: 视觉语义分析(截图优先)

输入:设计稿截图
任务:宏观结构判断
输出:区域划分表(类型/滚动方向/Item类型数/嵌套关系)
⏸️ 暂停,等用户确认

Phase 2: DSL精确提取(MCP结构化)

输入:MasterGo MCP getDsl
任务:精确数值提取 + 层级验证
交叉验证规则:

  • 截图显示滚动 + DSL未超出 → 仍按滚动处理
  • DSL中≥3个相同结构兄弟节点 → 强制RV
  • DSL中节点被clip裁切 → 可滚动
  • 同名前缀不同后缀 → 多ViewType
  • [RV]内嵌套[RV] → 嵌套列表
    输出:最终结构确认表
    ⏸️ 暂停,等用户确认

Phase 3: 代码生成

输入:确认后的结构 + DSL数据
生成顺序:

  1. 主布局(activity/fragment)
  2. 每个item布局(多ViewType则多个)
  3. 嵌套的内层item布局
  4. 数据模型(sealed class / data class)
  5. Adapter(含多ViewType分发 + 嵌套RV初始化)
  6. ViewHolder(每种类型一个)
  7. 页面初始化代码

Phase 4: 自检

  • RV边界正确?(无静态重复布局)
  • 多ViewType全部覆盖?
  • 嵌套RV独立Adapter + 性能优化?
  • 所有动态文本用tools:?
  • 滚动方向正确?
  • 所有动态View有id?
  • 颜色提取到colors.xml?

识别规则速查

信号 判定
≥3个相同结构兄弟节点 RecyclerView
图层名含[RV] RecyclerView
内容被clip裁切 可滚动
截图内容被屏幕截断 可滚动
[RV-Item/A] + [RV-Item/B] 多ViewType
[RV-Item]内含[RV/Inner] 嵌套RV
横向重复+超出宽度 横向RV

</code></pre>
<h4>④ 斜杠命令(快速调用)</h4>
<p><code>.claude/commands/d2a.md</code>:</p>
<pre class="language-markdown"><code>根据以下设计稿生成 Android 布局代码:

设计稿链接:$ARGUMENTS

输出路径:以我在对话中指定的地址为准;若我未指定,先问我,确认后再生成。

请严格按照 design-to-android skill 的流程执行:

  1. Phase 1: 先读截图做结构分析,输出分析表,等我确认
  2. Phase 2: 再用MCP获取DSL,交叉验证,输出确认表,等我确认
  3. Phase 3: 分步生成代码(XML → Model → Adapter → 初始化)
  4. Phase 4: 自检报告

重点关注:

  • 被截断的区域 → RecyclerView
  • 重复结构的不同变体 → 多ViewType
  • item内部的横向列表 → 嵌套RV
  • 所有动态数据 → tools:属性
    </code></pre>
    <p>使用方式:<code>/d2a https://mastergo.com/file/xxx?layer_id=yyy</code></p>
    <h4>⑤ MasterGo MCP 配置</h4>
    <pre class="language-bash"><code>claude mcp add mastergo -- npx -y @mastergo/magic-mcp --token=YOUR_MG_TOKEN
    </code></pre>
    <blockquote>
    <p>Token获取:MasterGo → 个人设置 → 开发者 → Personal Access Token
    MCP走结构化DSL通道,远比截图识别准确,务必优先使用。</p>
    </blockquote>


    <h2>三、适用边界</h2>
    <p>这套体系不是万能钥匙,效果建立在几个前提上,套用前先对照自己的情况:</p>
    <ul>
    <li><strong>技术栈是 XML + ViewBinding。</strong> 全部生成规范和代码模板都基于这套组合。Jetpack Compose 项目可以复用识别部分(命名规范、双通道阅读、RV 边界判定),但 Adapter 和多 ViewType 模板对应的是 LazyColumn + sealed class,生成规范需要重写。</li>
    <li><strong>依赖设计师配合命名。</strong> 设计师不加语义前缀时,第一层防线失效,只能靠双通道阅读和 Skill 规则兜底。结构仍然认得出来,但多 ViewType 和嵌套列表的出错会变多,Phase 1/2 的人工确认成本明显上升。</li>
    <li><strong>设计稿最好用了 Auto Layout。</strong> Phase 2 的方向和间距都从 Auto Layout 里读。完全靠绝对定位摆出来的稿子,这些信号是缺失的,提取到的数值失真会比较大。</li>
    <li><strong>只有截图、拿不到 DSL 时效果打折。</strong> “DSL 与截图矛盾”的根源就是单一输入源信息不完整。没有 MCP DSL 做交叉验证,结构判断只剩视觉线索,要做好人工确认轮次变多的心理准备。</li>
    <li><strong>深层嵌套和自绘控件不在覆盖范围内。</strong> 嵌套 RV 最多 3 层,超过就按生成规范提醒简化。自绘控件、复杂动画交互、ConstraintLayout 重度页面,本文的规则管不到,生成结果仍需要大量人工改写。</li>
    </ul>
    <p>一句话:本文针对标准列表/信息流类页面(RecyclerView 为主、多 ViewType、嵌套列表)最有效,离这个画像越远,准确率预期就要打得越低。</p>


    <h2>四、实战 Checklist</h2>
    <pre><code>设计侧 ──────────────────────────────────────────────
    ☐ 列表区域命名加 [RV/Outer] 或 [RV] 前缀
    ☐ Item组件命名 [RV-Item] 或 [RV-Item/变体名]
    ☐ 嵌套列表标注 [RV/Inner]
    ☐ 固定区域标注 [Fixed]
    ☐ 设计稿只画2~3个重复item(不要画太多增加干扰)

Prompt 侧 ────────────────────────────────────────────
☐ 先给截图做Phase 1结构分析
☐ 附带区域标注表(哪里是列表/方向/数据源)
☐ 附带数据模型JSON Schema
☐ 多ViewType附带映射表
☐ 嵌套RV明确声明层级关系和滚动方向

CLAUDE.md / Skill 侧 ────────────────────────────────
☐ 写入RV识别规则(≥3重复/clip裁切/[RV]命名)
☐ 写入多ViewType生成规范(sealed class + when分发)
☐ 写入嵌套RV生成规范(独立Adapter + 性能优化)
☐ 写入tools:属性规范
☐ 写入截图→DSL双通道阅读流程
☐ 写入分步生成+暂停确认流程
☐ 写入自检清单

生成流程 ────────────────────────────────────────────
☐ 确认输出路径(以用户输入的地址为准,未指定则先询问)
☐ Phase 1: 截图结构分析 → 人工确认
☐ Phase 2: DSL精确提取+交叉验证 → 人工确认
☐ Phase 3: XML布局 → 数据模型 → Adapter → 初始化
☐ Phase 4: 自检报告
☐ 生成完毕回显:完整落盘路径 + 文件清单
</code></pre>



<h2>五、写在最后</h2>
<p>不要指望 AI 从设计稿里“猜”出所有语义。截图负责语义,DSL 负责数值,命名负责身份,Skill 负责方法,四者结合起来,设计稿转码的准确率才有保障。</p>

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容