flutter-ui について
flutter-ui は、画面サイズに応じた Flutter UI の実装を支援するスキルです。パフォーマンス、デザイントークン、コンポーネント構成、レスポンシブレイアウト、アクセシビリティを扱います。
主な機能
- 01const の優先とリスト描画の最適化
- 02デザイントークンによるスタイル統一
- 03再利用可能な UI のコンポーネント化
- 04Slivers とアダプティブレイアウトの活用
- 05読み込み・エラー・空状態への対応
- 06キーボード操作とアクセシビリティセマンティクスのサポート
活用シーン
- 01スマートフォン、タブレット、デスクトップ向け UI の構築
- 02項目数の多いスクロールリストの最適化
- 03アプリの色、余白、タイポグラフィの統一
- 04アクセシビリティと操作状態の確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ dhruvanbhalara/ skills --skill flutter-uiインストール後、Claude Code で/flutter-uiを入力して読み込まれたか確認します。
詳細
1. パフォーマンスとレンダリング
- Const 優先:
constにできるすべてのウィジェットはconstにしなければなりません (MUST)。 - 遅延レンダリング: 10 件を超えるリストには
SliverList.builderまたはSliverGrid.builderを使用してください。 - 再描画境界: 複雑なアニメーションは
RepaintBoundaryでラップしてください。 - Impeller レンダリング: Impeller は iOS と Android のデフォルトのレンダリングエンジンです。カスタムキャンバスの描画が最適化されており、Skia 固有の挙動に依存していないことを確認してください。
- Isolate によるパース: 1MB を超える JSON には
compute()またはIsolateを使用してください。 - BuildContext の安全性: 非同期のギャップをまたいで
contextを使用する前にmountedを確認してください。
2. デザイントークン (テーマ)
AppColors、AppSpacing、AppRadius、AppTypography を使用してください。生の値をハードコードしてはいけません (NEVER)。
- 色:
context.colorScheme.primaryまたはAppColorsを使用してください。ライトモードとダークモードをサポートしてください。 - スペーシング:
AppSpacing.sm(8)、AppSpacing.md(16) などを使用してください。間隔にはSizedBoxを使用してください。 - 角丸: 一貫した角丸には
AppRadius.md(12) を使用してください。 - タイポグラフィ:
context.textTheme.bodyMediumを使用してください。テキストスケーリングをサポートしてください。
3. 再利用可能なコンポーネント
- 単一責任: 各コンポーネントは 1 つの明確な目的を持ちます。
- パラメーター化: カスタマイズ用のパラメーターを公開してください。
- 複雑さ: 複数回使用されるウィジェットやコードブロックは
core/views/widgetsに抽出してください。 - キー: テストからアクセスできるように、インタラクティブなウィジェットに
Key('feature_action_id')を割り当ててください。
4. ウィジェットとインタラクションのパターン
- 抽出: プライベートな
_build*()メソッドは厳格に禁止します (STRICTLY prohibit)。別々のウィジェットクラスに抽出してください。 - Slivers: 複雑なスクロール可能レイアウトには、Sliver を伴う
CustomScrollViewを優先してください。 - FAB: 主要な肯定的アクション (追加、作成) にはフローティングアクションボタンを使用してください。
- スクロールパディング: FAB や BottomBar が存在する場合は、重なりを防ぐために動的な下部パディングを追加してください。
- Pop の処理: 非推奨の
WillPopScopeウィジェットは使用しないでください (NEVER)。戻るナビゲーションを傍受またはブロックするには、標準のPopScopeウィジェットを使用してください。 - シートと画面: 複雑なフォームには
ModalBottomSheetよりも完全なScaffold画面を優先してください。
5. アダプティブ & レスポンシブデザインと一般的な修正
- モバイルファースト: モバイル向けに設計し、その後タブレット (
600-840dp) とデスクトップ (>840dp) に適応させてください。MediaQuery.sizeOf(context).widthを使用してください。 - LayoutBuilder: ウィジェットのレンダリングが画面全体ではなく直接の親の制約に依存する場合は、
LayoutBuilderを使用してください。 - セーフエリア & Android 15: デバイスのノッチやシステムバーのオーバーレイを避けるために、メインレイアウトを
SafeAreaでラップしてください。Android 15 ではデフォルトでエッジツーエッジのレンダリングが強制されるため、MediaQuery.paddingOf(context)またはSafeAreaを使用して、ウィジェットがシステムのステータスバーやナビゲーションバーの下でクリップされるのを防いでください。 - モジュール式 UI インポート: Flutter 3.44+ では
materialとcupertinoがコアフレームワークから分離されています。純粋な構造ウィジェットでは、明確なライブラリの分離を維持するためにpackage:flutter/widgets.dartのみをインポートしてください。 - オーバーフローの修正:
A RenderFlex overflowed...: 通常、ウィジェットがRowやColumnで利用可能なスペースよりも多くのスペースを要求していることを意味します。問題のあるウィジェットをExpandedまたはFlexibleでラップしてください。Vertical viewport was given unbounded height: スクロール可能なビューをネストした場合 (例えばColumn内のListView) によく発生します。ListViewにExpandedを使用するか、shrinkWrap: trueを設定してください。
- ルール: 固有の機能で厳密に必要とされない限り、画面の向きを固定しないでください。デスクトップユーザー向けにキーボードナビゲーションとホバー効果をサポートしてください。
6. レスポンシブレイアウトのパターン
LayoutBuilder と MediaQuery
| ツール | 使用する場合 | 戻り値 |
|---|---|---|
MediaQuery.sizeOf(context) | レイアウトが画面サイズに依存する場合 (アプリレベルのブレークポイント) | 画面の Size |
LayoutBuilder | レイアウトが親の制約に依存する場合 (ウィジェットレベル) | 親からの BoxConstraints |
ルール: ページレベルのレイアウトには MediaQuery を使用してください。コンテナに適応する再利用可能なコンポーネントには LayoutBuilder を使用してください。
ブレークポイントの規約
| ウィンドウクラス | 幅 | レイアウト | カラム数 |
|---|---|---|---|
| Compact | < 600dp | シングルカラム、下部ナビゲーション | 4 |
| Medium | 600-840dp | 2ペイン、ナビゲーションレール | 8 |
| Expanded | > 840dp | マルチペイン、サイドナビゲーション | 12 |
アダプティブレイアウトのパターン
Widget build(BuildContext context) {
final width = MediaQuery.sizeOf(context).width;
return switch (width) {
< 600 => const MobileLayout(),
< 840 => const TabletLayout(),
_ => const DesktopLayout(),
};
}
制約ウィジェット
| ウィジェット | 動作 | 使用する場面 |
|---|---|---|
Expanded | Row/Column 内の残りの空間をすべて埋める | 子を伸縮させたい場合 |
Flexible | 子を残りの空間より小さくできる | 子が自然なサイズを持つ場合 |
FractionallySizedBox | 親に対する割合でサイズを指定(例: 0.5 = 50%) | 比例レイアウト |
ConstrainedBox | 最小・最大の制約を設定 | 制限付きの柔軟性 |
SizedBox | 固定の絶対サイズ | 正確なサイズが判明している場合 |
7. UI の状態とアクセシビリティ
- 状態: Loading、Error、Empty の各状態を常に処理し、明確なメッセージを表示します。
- アクセシビリティ:
Semanticsラベルを含めます。48x48 dp のタッチターゲットを確保します。WCAG AA のコントラストを満たします。
コメント
Markdown 対応