# Figma Android Xml

> Generate high-fidelity Android XML layouts from Figma MCP by extracting tokens/resources first, mapping components, then implementing ConstraintLayout and screenshot-diff fixes.

- **Type:** Skill
- **Install:** `agentstack add skill-jahonn-figma-android-xml-figma-android-xml`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [jahonn](https://agentstack.voostack.com/s/jahonn)
- **Installs:** 0
- **Category:** [Content & Media](https://agentstack.voostack.com/c/content-and-media)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [jahonn](https://github.com/jahonn)
- **Source:** https://github.com/jahonn/figma-android-xml

## Install

```sh
agentstack add skill-jahonn-figma-android-xml-figma-android-xml
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Figma → Android XML High-Fidelity Implementation

Use this skill when the user asks to implement, restore, convert, review, or refine Android **XML View-system** UI from a Figma design, especially when they care about high visual fidelity.

This skill is not a one-shot Figma-to-code generator. It enforces this workflow:

1. Read and normalize the Figma design.
2. Extract Android resources and component mappings.
3. Generate resources first.
4. Generate XML layout second.
5. Add only the minimal Kotlin/ViewBinding code needed.
6. Validate with build/lint when possible.
7. Iterate using screenshot differences.

Do not switch to Jetpack Compose unless the user explicitly asks.

## Core Principles

- Treat Figma as a design specification, not as absolute-positioned code.
- Prefer Android resource references over hardcoded values.
- Prefer `ConstraintLayout` for complex screens and shallow hierarchy.
- Preserve spacing, typography, corner radius, image scale type, component states, and system-bar assumptions.
- Never hide uncertainty. If Figma data, assets, fonts, or states are missing, state the gap and choose the least risky implementation.
- Do not generate a giant final layout before producing the design specification and resource plan.

## Required First Step

Before editing files, inspect the project and the Figma input.

### Project inspection

Check, as available:

- Gradle modules and Android plugin setup.
- Whether the screen uses Activity, Fragment, ViewBinding, DataBinding, or legacy manual binding.
- Existing `res/values/colors.xml`, `dimens.xml`, `styles.xml`, `themes.xml`, `strings.xml`.
- Existing custom widgets, base layouts, adapters, drawable naming conventions, and typography resources.
- ConstraintLayout, RecyclerView, AppCompat, and Material Components availability.
- minSdk, targetSdk, and whether edge-to-edge / WindowInsets handling is already present.

### Figma inspection

Use configured Figma MCP tools when available. Read, if possible:

- design context
- metadata
- variables / styles
- component names and variants
- selected frame screenshot
- asset export information

If Figma MCP is unavailable or incomplete, use any provided screenshot/specs and mark missing values as assumptions. Do not invent exact colors, fonts, or dimensions when they are not available.

## Output Gate 1: Design Spec Report

Before writing code, output a concise implementation report with these sections:

1. **Target screen**
   - Frame name and size
   - Android baseline width assumption, for example 360dp, 375dp, 390dp, 393dp, or project-defined width
   - Whether the Figma frame includes status bar / navigation bar
   - Scroll behavior

2. **Resource tokens**
   - Colors → proposed `@color/...` names
   - Spacing → proposed `@dimen/space_*` names
   - Sizes → heights, widths, icon sizes, image sizes
   - Radius → proposed `@dimen/radius_*` names
   - Typography → text appearances, font family, size, weight, line height, letter spacing
   - Elevation / shadow approximation

3. **Layout structure**
   - Root layout choice
   - Major sections
   - Reusable item layouts
   - RecyclerView / ScrollView / NestedScrollView decisions

4. **Component mapping**
   - Figma Button/Input/Card/TopBar/ListItem/etc. → Android view or custom component
   - States: default, pressed, disabled, selected, error, loading

5. **Assets**
   - Images to export
   - Icons to convert to VectorDrawable
   - Image scale type: `centerCrop`, `fitCenter`, `centerInside`, etc.

6. **Risks / assumptions**
   - Missing fonts
   - Unknown system bars
   - Unknown responsive behavior
   - Missing states
   - Ambiguous image crop or shadow

Only after this report should implementation begin.

## Implementation Order

### Phase 1: Resources first

Create or update resources before page XML:

- `res/values/colors.xml`
- `res/values/dimens.xml`
- `res/values/styles.xml`
- `res/values/strings.xml` when static strings are needed
- `res/drawable/bg_*.xml` shape drawables
- `res/drawable/selector_*.xml` state selectors
- `res/drawable/ic_*.xml` vector drawables when icons are available

Rules:

- All colors must be referenced through `@color/...`.
- All layout dimensions, margins, paddings, icon sizes, corner radii, and text sizes must be referenced through `@dimen/...`, unless the project convention intentionally keeps common values inline.
- Use clear token names, not Figma layer names.
- Reuse existing resources if semantically equivalent.
- Do not duplicate near-identical colors or dimens without explaining why.

Recommended naming:

```xml
#FFFFFF
#111827
#6B7280
#2563EB
```

```xml
4dp
8dp
12dp
16dp
12dp
48dp
16sp
24sp
```

### Phase 2: Text styles

Define reusable text styles in `styles.xml` when the project has no better convention.

Use `TextAppearance.App.*` for reusable text appearances and `Widget.App.*` for widgets/components.

Text fidelity rules:

- Set `android:includeFontPadding="false"` unless the project convention or design requires default font padding.
- Preserve `fontFamily`, `textSize`, `lineHeight`, `textColor`, `textStyle`, and `letterSpacing` when available.
- If exact font files are missing, use the closest available font and explicitly report the gap.
- For multi-line text, preserve line height and max lines when specified.

Example:

```xml

    @font/inter_semibold
    @dimen/text_size_20
    @color/color_text_primary
    false

```

### Phase 3: Drawable and selector resources

For Figma fills, strokes, and corners, create shape drawables:

```xml

    
    
    

```

For buttons and stateful components, use selectors rather than runtime hacks:

- `selector_button_primary.xml`
- `selector_input_border.xml`
- `selector_card_background.xml`

Approximate Figma shadows carefully. XML View shadows are limited; use elevation for Material-like shadows, drawable layers for simple shadows, or document that an exact shadow requires a custom drawable/view.

### Phase 4: Layout XML

Use `ConstraintLayout` as the default root for complex screens.

Layout rules:

- Root screen: usually `android:layout_width="match_parent"` and `android:layout_height="match_parent"`.
- Inside `ConstraintLayout`, use `0dp` for dimensions that should stretch between constraints. Do not use child `match_parent` inside `ConstraintLayout` unless there is a project-specific reason.
- Use `wrap_content` for text height unless fixed height is explicitly required.
- Avoid translating Figma absolute x/y positions into a pile of fixed margins.
- Avoid excessive nested `LinearLayout` hierarchies.
- Use `LinearLayout` only for simple vertical/horizontal groups where it improves clarity.
- Use `FrameLayout` for overlays, badges, scrims, or stacked content.
- Use `RecyclerView` for repeating content and create separate `item_*.xml` files.
- Use `NestedScrollView` only when the whole page scrolls and there is no large/repeating list.
- Add `tools:` preview attributes for design-time content, not runtime behavior.
- Keep IDs meaningful: `titleText`, `primaryButton`, `bannerImage`, `contentRecyclerView`.

Constraint rules:

- Anchor sections to sibling or parent constraints, not arbitrary coordinates.
- Use `app:layout_constraintDimensionRatio` for fixed-ratio images/cards.
- Use chains for evenly distributed horizontal or vertical items.
- Use barriers when long dynamic text affects alignment.
- Use guidelines only when the design genuinely uses a fixed percentage or shared alignment rail.

### Phase 5: Figma-to-XML conversion rules

Use these mappings unless project conventions override them:

| Figma concept | Android XML implementation |
|---|---|
| Vertical Auto Layout | `LinearLayout vertical` for simple groups; `ConstraintLayout` for complex groups |
| Horizontal Auto Layout | `LinearLayout horizontal` for simple groups; `ConstraintLayout` for adaptive alignment |
| Fill container | `0dp` + constraints, or root `match_parent` |
| Hug contents | `wrap_content` |
| Fixed size | named `@dimen/...` |
| Gap | margin or parent padding from `@dimen/...` |
| Padding | parent `android:padding*` from `@dimen/...` |
| Overlay / badge | `FrameLayout` or constrained overlay |
| Figma image Fill | `ImageView android:scaleType="centerCrop"` |
| Figma image Fit | `ImageView android:scaleType="fitCenter"` |
| Icon SVG | Convert to VectorDrawable XML |
| Button variants | style + background selector + text color selector |
| Input variants | background/border selector + helper/error text |

### Phase 6: System bars and insets

Always decide whether the Figma frame includes status bar and navigation bar.

- If the Figma frame includes system bars, do not duplicate their space in XML.
- If the Figma frame excludes system bars, ensure the Activity/Fragment handles WindowInsets or existing project edge-to-edge conventions.
- If targetSdk is 35 or higher, explicitly check whether edge-to-edge behavior affects the screen.
- Do not silently add top/bottom padding without explaining whether it corresponds to system bars, toolbar height, or content spacing.

### Phase 7: Kotlin / ViewBinding

Only add Kotlin when needed for:

- wiring ViewBinding
- setting adapters
- loading images
- applying WindowInsets
- binding sample/static data
- handling simple states requested by the user

Do not put visual dimensions, colors, or spacing in Kotlin unless unavoidable. Keep UI styling in XML resources.

If the screen has a list:

- Create `item_*.xml`.
- Create or update adapter only if required.
- Keep item spacing faithful to Figma.
- Use stable, simple placeholder data if the user has not supplied real data.

## Validation

After implementation, validate in this order where possible:

1. XML resource syntax and duplicate names.
2. Gradle build or at least module resource merge:
   - `./gradlew assembleDebug`
   - or the narrowest relevant Gradle task available.
3. Lint or Android Studio warnings when available.
4. Manual layout review against the Figma spec.
5. Screenshot comparison, if screenshots are available.

If running Gradle is not practical, report that validation was limited and perform static XML review.

## Screenshot Difference Workflow

When the user provides both Figma and app screenshots, or when screenshots can be generated:

1. Compare layout first: root padding, top/bottom offsets, section positions, scroll area.
2. Compare typography: font weight, text size, line height, baseline, text color.
3. Compare spacing: margins, inner padding, list gaps, icon-text gaps.
4. Compare components: radius, stroke, background, selector states.
5. Compare imagery: crop, aspect ratio, alignment, clipping.
6. Compare system bars/insets.

Output a prioritized diff list before making changes. Fix only necessary differences. Do not rewrite the whole screen unless the structure is fundamentally wrong.

## Final Response Format

When finishing an implementation, summarize:

- Files changed.
- Resources added or reused.
- Layout/component structure.
- Known deviations from Figma.
- Validation performed and result.
- Next screenshot-diff steps, if needed.

## Real-World Pitfalls (battle-tested gotchas)

These are non-obvious failures that have caused multiple debug rounds. Check each one BEFORE the user asks "why is X broken".

### Asset format pitfalls

#### 1. SVG-as-PNG trap (most common)
- **Symptom**: Downloaded `.png` files are present at sane sizes (700B-2KB) but `ImageView` renders blank, no error.
- **Cause**: Figma exports vector nodes (Group with paths/rects/circles) as **raw SVG content** even when the asset URL looks like it returns a PNG. The file extension is `.png` but the bytes start with ``. Android's `BitmapFactory` cannot decode SVG → silent blank.
- **Detection**: After every batch download, check PNG magic bytes:
  ```python
  with open(path, 'rb') as f:
      ok = f.read(8) == b'\x89PNG\r\n\x1a\n'
  ```
  Or `file path.png` should report `PNG image data`, not `SVG Scalable Vector Graphics image`.
- **Fix**: Convert each SVG to Android `VectorDrawable` XML (handles ``/``/``/`` with `fillColor`/`strokeColor`/`strokeWidth`). Save as `.xml` in `drawable/`, **delete the broken `.png`** (Android resource system: `@drawable/foo` matches either `.png` or `.xml` — having both causes duplicate-resource error).
- **Quick rule**: anything that appears as a `` group with shape primitives in Figma → expect SVG export → expect to convert.

#### 2. SVG `` (drop shadow / inner shadow / blur) doesn't translate
- **Symptom**: Converted VectorDrawable shows the shape but missing the shadow/glow that was visible in Figma.
- **Cause**: VectorDrawable does not support `feGaussianBlur` / `feDropShadow` / `feColorMatrix`. SVG `` blocks are silently dropped during conversion.
- **Fix**: Approximate shadows with Android `android:elevation` (Material drop shadow), or for non-rectangular cards use `CardView` + `cardElevation`. Inner shadows generally cannot be reproduced without a full bitmap render.

#### 3. SVG `linearGradient` → use Android shape ``
- **Symptom**: VectorDrawable shows solid color where Figma had a gradient fill.
- **Cause**: `` referenced via `fill="url(#paint0_linear...)"` requires either inline `` (API 24+) inside the ``, or rewriting the whole asset as a `shape` drawable with ``.
- **Fix**: For simple gradients on rect/oval, **prefer hand-authored `shape` drawable** with `` — it's cleaner than fighting VectorDrawable inline gradients.

#### 4. SVG `mask group` (alpha mask / clip path) cannot run in XML View system
- **Symptom**: Figma hero illustration cropped to a specific shape — Android shows the un-cropped photo.
- **Cause**: Figma's mask group uses alpha masking on raster images. The View system has no built-in alpha mask. Compose has it. `BitmapShader` + custom View can do it.
- **Fix**: Use the source photo asset directly without mask (90-95% visual match), or write a small custom `MaskedImageView` if pixel-perfect is required. Document the deviation.

#### 5. Asset filename ↔ content mapping is unreliable
- **Symptom**: Tab a/b state PNGs render but selected tab shows the wrong icon (e.g., clicking "device" makes "mine" turn blue).
- **Cause**: When pre-downloaded by an earlier script, naming conventions (`_a` for active, `_b` for inactive) may have been applied inconsistently — one tab's `_a` is blue while another's `_a` is gray.
- **Fix**: For state-pair assets, **read each PNG once** to verify content matches the name. Then either rename files on disk OR adjust selectors/Java to match actual content. Don't fix it twice.

#### 6. Figma asset URLs are short-lived (7-day TTL)
- **Symptom**: `curl ` succeeds but downloads 0 bytes or HTML error.
- **Cause**: URLs returned by `get_design_context` expire ~7 days after the call. Asset URLs cached from earlier sessions may be dead.
- **Fix**: Re-call `get_design_context` for fresh URLs immediately before downloading. Do not store/reuse URLs across sessions.

### Layout / inset pitfalls

#### 7. `match_parent` + `weight=1` collision in LinearLayout
- **Symptom**: Sibling views (tab bar, footer) get pushed off-screen when a weighted child is present.
- **Cause**: Setting `layout_height="match_parent"` on a child with `layout_weight="1"` causes some Android versions to allocate the child the full parent height before applying weight, eating space meant for fixed-size siblings.
- **Fix**: Use `layout_height="0dp"` + `layout_weight="1"` (the canonical LinearLayout weight pattern). Same for horizontal: `layout_width="0dp"` + `layout_weight`.

#### 8. Edge-to-edge enforced on `targetSdk` 35+
- **Symptom**: Top of screen (back button, title) hidden behind the system status bar.
- **Cause**: Android 15 (`targetSdk=35`) makes app windows fullscreen by default, regardless of theme settings. Activities must explicitly handle insets.
- **Fix**: Add `android:fitsSystemWindows="true"` to the **Activity root layout** (not just individual fragments). For multi-fragment Activities, putting it on the Activity root means all fragments

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [jahonn](https://github.com/jahonn)
- **Source:** [jahonn/figma-android-xml](https://github.com/jahonn/figma-android-xml)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** yes
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-jahonn-figma-android-xml-figma-android-xml
- Seller: https://agentstack.voostack.com/s/jahonn
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
