將 UI 截圖轉換為符合專案規範的 Jetpack Compose 程式碼
將 UI 設計截圖轉換為符合專案規範的 Jetpack Compose 程式碼。
/gen-compose-jetpack {圖片路徑}
/gen-compose-jetpack {圖片路徑} --feature {功能名稱}
/gen-compose-jetpack {圖片1} {圖片2} --feature {功能名稱}
圖片存放位置:doc/designs/ 目錄下
| 參數 | 必填 | 說明 |
|---|---|---|
{圖片路徑} | 是 | UI 截圖檔案路徑(支援 png, jpg, jpeg, webp) |
--feature | 否 | 指定功能名稱,覆蓋建議的名稱 |
驗證圖片路徑 → 分析 UI → 詢問 Navigation → 產生核心 UI(含 @Preview)
↓
編譯驗證(自動修復)
↓
[確認點] 預覽 UI
↓
┌──────────────────────┼──────────────────────┐
↓ ↓ ↓
選項 1 選項 2 選項 3
繼續生成後續 重新分析圖片 自行輸入調整
↓ ↓ ↓
產生完整架構 回到 Gemini 分析 重新生成 → 回到確認點
↓
編譯驗證(最終)
驗證規則:
doc/designs/ 目錄下圖片不存在:
錯誤:找不到圖片檔案
請確認圖片路徑正確:{圖片路徑}
預期圖片位置:
doc/designs/
├── login.png
├── profile.png
└── ...
圖片格式不支援:
錯誤:不支援的圖片格式
支援的圖片格式:.png, .jpg, .jpeg, .webp
請提供正確格式的設計圖。
圖片不在 doc/designs/ 目錄:
錯誤:圖片必須放在 doc/designs/ 目錄下
請將設計圖移至 doc/designs/ 目錄後再執行。
模型指定:使用
gemini-3-pro模型進行圖片分析
使用 prompts/image-analysis-prompt.md 分析圖片,輸出 JSON 格式的 UI 描述,包含:
screen_type: 畫面類型suggested_feature_name: 建議的功能名稱suggested_screen_name: 建議的畫面名稱ui_elements: UI 元素列表layout_structure: 佈局結構state_requirements: 狀態需求complexity_level: 複雜度等級split_recommendation: 元件拆分建議詢問使用者:
問題:是否需要產生 Navigation 相關程式碼?
選項:
僅產生以下檔案,讓使用者可以先預覽 UI 佈局:
注意:Step 4A 不產生 Route,只產生 Stateless 的 Screen。 Route 與 ViewModel 將在 Step 4B 一起產生。
app/src/main/java/com/example/realtimeassistant/feature/{功能名}/ui/
├── screen/{功能名}Screen.kt # Stateless Screen(含 @Preview)
├── state/{功能名}UiState.kt # UI 狀態資料類別
├── state/{功能名}Event.kt # 使用者事件定義
├── state/{功能名}Effect.kt # 一次性副作用定義
└── component/{元件名}.kt # 拆分的元件(如有)
app/src/main/res/values/strings.xml # 新增字串資源
app/src/main/java/.../core/ui/theme/Color.kt # 如有新顏色
重要:Screen 檔案必須包含
@Preview函式,讓使用者可以在 Android Studio 預覽 UI 佈局。
驗證指令:
./gradlew clean compileDebugSources
說明:使用
clean compileDebugSources而非compileDebugKotlin, 以解決 Android Studio 增量編譯導致的 R.class 緩存同步問題 (NoSuchFieldError或Resources$NotFoundException)。 此指令比assembleDebug更快,因為只編譯不打包。
問題:編譯驗證連續失敗 5 次,請選擇下一步:
選項:
編譯成功後,詢問使用者:
問題:核心 UI 已產生並通過編譯,請在 Android Studio 預覽 @Preview 確認佈局是否正確:
選項:
僅在 Step 4A.6 選擇「繼續生成後續」時執行
補充以下檔案:
screen/{功能名}Screen.kt - 新增 {功能名}Route Composableviewmodel/{功能名}ViewModel.ktviewmodel/{功能名}ViewModelFactory.ktapp/src/main/java/com/example/realtimeassistant/feature/{功能名}/domain/
├── model/{Model}.kt # 領域模型(如有需要)
├── repository/{功能名}Repository.kt # Repository 介面
└── usecase/Get{功能名}UseCase.kt # 業務邏輯封裝
app/src/main/java/com/example/realtimeassistant/feature/{功能名}/data/
└── repository/{功能名}RepositoryImpl.kt # Repository 實作
app/src/main/java/com/example/realtimeassistant/core/navigation/
├── NavRoute.kt # 新增路由定義
└── NavGraph.kt # 新增 composable
驗證指令:
./gradlew compileDebugKotlin
問題:編譯驗證連續失敗 5 次,請選擇下一步:
選項:
執行完成後,輸出以下格式的結果:
## Gemini 產生 Jetpack Compose 執行結果
### 功能名稱
{功能名}
### 產生的檔案
**UI 層**
- `app/src/main/java/.../feature/{功能名}/ui/screen/{功能名}Screen.kt`
- `app/src/main/java/.../feature/{功能名}/ui/state/{功能名}UiState.kt`
- `app/src/main/java/.../feature/{功能名}/ui/state/{功能名}Event.kt`
- `app/src/main/java/.../feature/{功能名}/ui/state/{功能名}Effect.kt`
- `app/src/main/java/.../feature/{功能名}/ui/viewmodel/{功能名}ViewModel.kt`
- `app/src/main/java/.../feature/{功能名}/ui/viewmodel/{功能名}ViewModelFactory.kt`
**Domain 層**
- `app/src/main/java/.../feature/{功能名}/domain/model/{Model}.kt`
- `app/src/main/java/.../feature/{功能名}/domain/repository/{功能名}Repository.kt`
- `app/src/main/java/.../feature/{功能名}/domain/usecase/Get{功能名}UseCase.kt`
**Data 層**
- `app/src/main/java/.../feature/{功能名}/data/repository/{功能名}RepositoryImpl.kt`
### 新增的字串資源
| 鍵值 | 內容 |
|------|------|
| xxx | 對應文字 |
### Navigation
{是否產生 Navigation 程式碼:是/否}
### 編譯驗證
✓ 編譯成功
references/compose/guidelines.md - UI 規範references/compose/navigation.md - 導航規範references/compose/performance.md - 效能規範references/compose/accessibility.md - 無障礙規範references/file-structure.md - 檔案放置規範references/mapping/ui-elements.md - UI 元素與 Layout 對照references/mapping/colors.md - 顏色角色與轉換對照references/mapping/typography.md - 文字樣式與字體對照references/mapping/dimensions.md - 尺寸轉換對照references/mapping/backgrounds.md - 背景處理策略references/templates/code-templates.md - UDF 架構與各層模板| 禁止項目 | 正確做法 |
|---|---|
| 硬編碼字串 | stringResource(R.string.xxx) |
| 硬編碼顏色 | MaterialTheme.colorScheme.xxx |
collectAsState | collectAsStateWithLifecycle |
| SharedFlow(replay=0) 發送一次性事件 | 使用 Channel |
| LazyColumn 沒有 key | key = { it.id } |
| 觸控區域小於 48dp | minimumInteractiveComponentSize() |
| 功能性圖示缺少 contentDescription | 提供無障礙描述 |
| UiState 使用 List | 使用 ImmutableList |
/gen-compose-jetpack doc/designs/login_step1.png doc/designs/login_step2.png --feature auth
產生結構:
feature/auth/
├── ui/
│ ├── screen/
│ │ ├── LoginStep1Screen.kt
│ │ └── LoginStep2Screen.kt
│ ├── state/
│ │ ├── AuthUiState.kt
│ │ ├── AuthEvent.kt
│ │ └── AuthEffect.kt
│ ├── viewmodel/
│ │ ├── AuthViewModel.kt
│ │ └── AuthViewModelFactory.kt
│ └── component/
│ └── {共用元件}.kt
├── domain/
│ ├── model/
│ ├── repository/AuthRepository.kt
│ └── usecase/GetAuthUseCase.kt
└── data/
└── repository/AuthRepositoryImpl.kt
/gen-compose-jetpack doc/designs/login.png doc/designs/profile.png doc/designs/cart.png
產生結構:
feature/login/...
feature/profile/...
feature/cart/...
# 單一畫面
/gen-compose-jetpack doc/designs/login.png
# 指定功能名稱
/gen-compose-jetpack doc/designs/user_form.png --feature user_profile
# 批次處理同一功能
/gen-compose-jetpack doc/designs/checkout_1.png doc/designs/checkout_2.png --feature checkout
產生程式碼後,確認:
stringResource)MaterialTheme.colorScheme)collectAsStateWithLifecycleChannelImmutableListreferences/file-structure.md./gradlew compileDebugKotlin)