開発Tips

Android 15 の強制エッジツーエッジで下部が隠れる問題を潰す

Android 15(targetSdk 36)では エッジツーエッジが強制され、アプリのコンテンツがシステムバーの下まで描画されます。「ぽんっ!」(旧称:でいりんぐ)でも、一部画面でリストの末尾やボタンがナビゲーションバーに隠れる問題が出たので、その修正パターンを残します。

背景(当時の状況)

Android 15(targetSdk 36)対応を進めていた 2026-07-12、強制エッジツーエッジで一部画面の下端が隠れることに気づきました。全画面を見て回ると、隠れるのは決まった条件の画面だけ——という切り分けができたのが、統一的な直し方にたどり着けた理由です。

隠れやすいのはこの2パターン

全画面を調べたところ、隠れるのは決まった条件でした。

  1. bottomNavigationBar を持たないフルスクリーン画面。 下端の余白が固定値や 0 のままだと、末尾がナビゲーションバーに潜り込む。
  2. 広告なし(プレミアム)で下部バナーが消える画面。 通常は下部に広告バナーがあるぶんの高さで末尾が守られていたのに、プレミアムでバナーが SizedBox.shrink() になると、その高さが消えて末尾が隠れる。

2 番目は「無料だと出ないが、プレミアムだと出る」ので、テストアカウントの状態次第で見落としやすい罠でした。

統一修正: viewPadding を下端に加算する

修正は、下端の余白にシステムのインセットを加算する形で統一しました。

// スクロールや下部要素の bottom padding にナビゲーションバー分を加算
final bottomInset = MediaQuery.viewPaddingOf(context).bottom;

ListView(
  padding: EdgeInsets.only(bottom: 16 + bottomInset),
  children: [ /* ... */ ],
);
  • 画面 bodySafeArea(top: false) で包む(上はアプリバー等で処理済みのため下だけ守る)。
  • ボトムシートuseSafeArea: true を付ける。
  • IME(キーボード)対策MediaQuery.viewInsetsOf(context).bottom を使う(viewPadding とは別物)。

viewPaddingOf は「システム UI に恒常的に取られる余白(ナビゲーションバー等)」、viewInsetsOf は「一時的に覆う余白(キーボード)」で、用途が違う点に注意です。

非推奨 API 警告は「アプリ側で直せない」ことがある

対応中、Play Console で setStatusBarColor / setNavigationBarColor 系の非推奨 API 警告が出ていました。調べると、これはアプリのコードではなく Flutter エンジン内部の呼び出しが出どころでした。

  • 使用中の Flutter では、当該 API 呼び出しは Build.VERSION.SDK_INT < 35 でガード済みで、Android 15+ の実機では呼ばれず機能的な実害はゼロ
  • ただし Play Console は AAB のバイトコードを静的解析するため、ランタイムでガードしていても警告表示自体は残る

つまりこれは慌ててバナーを pin したりする話ではなく、Flutter をアップグレードして当該参照が消えたバージョンで、警告が消えたか Play Console で確認する類の項目です。

まとめ

  • Android 15 の強制エッジツーエッジでは、bottomNavigationBar なし画面広告が消える画面で下端が隠れやすい。
  • 修正は viewPaddingOf(...).bottom を下端に加算 + SafeArea(top:false) + ボトムシートの useSafeArea で統一できる。IME は viewInsetsOf
  • Play Console の非推奨 API 警告は、フレームワーク由来で実害がないケースがある。出どころを確認し、アプリ側の緊急対応が要るのかを見極めるのが大事です。