Communityコーディング&開発github.com

kmp-edge-to-edge

Compose Multiplatform で Android と iOS のエッジツーエッジレイアウトを実現するスキル。プラットフォームごとの有効化、Scaffold、リスト、ボトムバー、キーボード(IME)、ディスプレイカットアウト、システムバーのアイコンコントラスト、広告バナーを画面端まで描画します。スクリーンスキャフォールドの構築、ステータスバー・ナビゲーションバー・ノッチ・キーボードの下にコンテンツが隠れる問題の修正、または Android 15 以降をターゲットにする際に使用します。

kmp-edge-to-edge とは?

これは Compose Multiplatform アプリケーションでエッジツーエッジレイアウトを実装するためのスキルです。Android では SDK 35 以降でエッジツーエッジが必須となり、36 ではオプトアウトが削除されます。iOS でもステータスバーやホームインジケーターの下に描画することが期待されます。このスキルは、Scaffold を使った標準的なレイアウトから、キーボード(IME)への対応、フルブリードコンテンツ、システムバーのアイコンコントラスト調整、広告バナーの適切な配置までをカバーします。主なルールは「背景はシステムバーの背後に描画し、コンテンツとコントロールはインセットでパディングする」ことです。Android の `enableEdgeToEdge()` や iOS の `ignoresSafeArea()` による有効化方法、`innerPadding` の正しい使い方、インセットの二重適用を防ぐ方法など、実践的なガイドラインが提供されています。このスキルは Claude Code, Cursor, Codex などの AI エージェントで使用でき、開発者がエッジツーエッジ対応を最初から正しく実装するのに役立ちます。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/wasey-rao/kmp-agent-studio/tree/HEAD/kmp-studio/skills/kmp-edge-to-edge

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Compose Multiplatform でのエッジツーエッジ

Android は SDK 35 以降をターゲットとするアプリにエッジツーエッジを強制し、36 ではオプトアウトが削除されます。iOS アプリはステータスバーとホームインジケーターの下に描画することが期待されます。最初からすべての画面をエッジツーエッジで構築しましょう。

ルール: 背景はシステムバーの背後に描画し、コンテンツとコントロールはインセットでパディングします。

有効化

Android (androidApp の MainActivity)、setContent の前に:

override fun onCreate(savedInstanceState: Bundle?) {
    enableEdgeToEdge()
    super.onCreate(savedInstanceState)
    setContent { App() }
}

マニフェストでアクティビティに android:windowSoftInputMode="adjustResize" を設定し、IME インセットが Compose に届くようにします。

iOS (ContentView.swift): Compose が画面全体を所有するようにします。そうしないと SwiftUI が先にセーフエリアを適用し、Compose がインセットをゼロと認識します。

ComposeView().ignoresSafeArea()

Scaffold がほとんどの作業を行います

Scaffold(
    topBar = { TopAppBar(title = { Text(title) }) },          // ステータスバー用に自身をパディング
    bottomBar = { NavigationBar { /* ... */ } },              // ナビゲーションバー用に自身をパディング
) { innerPadding ->
    LazyColumn(
        contentPadding = innerPadding,                         // コンテンツはバーの下をスクロール
        modifier = Modifier.fillMaxSize(),
    ) { /* items */ }
}
  • 常に innerPadding を使用します。リストの場合は contentPadding として渡すことで、項目が半透明のバーの背後をスクロールできるようにします。スクロールしないコンテンツには Modifier.padding(innerPadding) を使用します。
  • Material 3 のバーは自身のインセットを消費します。TopAppBar の上に statusBarsPadding() を追加しないでください。
  • ネストされた Scaffold はパディングが二重になります。内側の Scaffold には contentWindowInsets = WindowInsets(0) を指定するか、外側のコンテンツに consumeWindowInsets(innerPadding) を適用します。

Scaffold のない画面

Box(Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)) {   // 背景が画面を埋める
    Column(Modifier.fillMaxSize().windowInsetsPadding(WindowInsets.safeDrawing)) { /* content */ }
}

WindowInsets.safeDrawing はステータスバー、ナビゲーションバー、ディスプレイカットアウト、キーボードをカバーします。ジェスチャーが重要な場合は safeContent を使用します。インセットのパディングは、コンテンツを所有するレベルで一度だけ適用し、親と子の両方には適用しないでください。

キーボード

  • 入力画面: スクロールコンテナに Modifier.imePadding() を使用するか、safeDrawing を使用します(safeDrawing には既に IME が含まれています)。
  • キーボードの上に表示する必要がある下部ボタン: スクフォールドの bottomBar に Modifier.imePadding() を付けて配置するか、WindowInsets.ime.union(WindowInsets.navigationBars) を使用します。
  • コンテンツをスクロール可能にして、フォーカスされたフィールドが表示されるようにします。

フルブリードコンテンツ

画像、マップ、ビデオ、カメラプレビューはインセットを無視して画面全体を埋める必要があります。コントロールをその上にオーバーレイし、コントロールのみを WindowInsets.safeDrawing でパディングします。

システムバーのコントラスト

バーは透明なので、アイコンのコントラストはあなたの責任です。Android では enableEdgeToEdge() がシステムテーマから明るいまたは暗いアイコンを選択します。アプリに独自のテーマ切り替えがある場合は、テーマが変更されたときに一致する SystemBarStyle を指定して再度呼び出します。3ボタンナビゲーションでは Android が半透明のスクリムを追加します。ボトムバーが既に不透明な背景を提供している場合を除き、そのままにしておきます。

広告バナー

下部のバナーはスクフォールドの bottomBar スロット内、ナビゲーションバーのインセットの上に配置し、その高さを予約してコンテンツがジャンプしないようにします。バナーをジェスチャーバーの下に置いたり、ナビゲーションコントロールと重ねたりしないでください。これはレイアウトのバグであると同時に広告ポリシーの問題でもあります。

すべての画面のチェックリスト

  • 背景が上部と下部の物理エッジに達している。
  • テキストやコントロールがステータスバー、カットアウト、ナビゲーションバー、ホームインジケーターの下にない。
  • 最後のリストアイテムがボトムバーの上まで完全にスクロールできる。
  • フォーカスされたテキストフィールドがキーボードを開いた状態で表示され続ける。
  • 横向き(カットアウトが側面にある場合)とダークテーマで正しく表示される。
  • インセットは一度だけ適用され、二重になっていない。

Google の edge-to-edge スキルがインストールされている場合は、これを使用して Android 固有のトラブルシューティングを行ってください。

関連スキル