Android 15 の強制エッジツーエッジで下部が隠れる問題を潰す
Android 15(targetSdk 36)では エッジツーエッジが強制され、アプリのコンテンツがシステムバーの下まで描画されます。「ぽんっ!」(旧称:でいりんぐ)でも、一部画面でリストの末尾やボタンがナビゲーションバーに隠れる問題が出たので、その修正パターンを残します。
背景(当時の状況)
Android 15(targetSdk 36)対応を進めていた 2026-07-12、強制エッジツーエッジで一部画面の下端が隠れることに気づきました。全画面を見て回ると、隠れるのは決まった条件の画面だけ——という切り分けができたのが、統一的な直し方にたどり着けた理由です。
隠れやすいのはこの2パターン
全画面を調べたところ、隠れるのは決まった条件でした。
bottomNavigationBarを持たないフルスクリーン画面。 下端の余白が固定値や 0 のままだと、末尾がナビゲーションバーに潜り込む。- 広告なし(プレミアム)で下部バナーが消える画面。 通常は下部に広告バナーがあるぶんの高さで末尾が守られていたのに、プレミアムでバナーが
SizedBox.shrink()になると、その高さが消えて末尾が隠れる。
2 番目は「無料だと出ないが、プレミアムだと出る」ので、テストアカウントの状態次第で見落としやすい罠でした。
統一修正: viewPadding を下端に加算する
修正は、下端の余白にシステムのインセットを加算する形で統一しました。
// スクロールや下部要素の bottom padding にナビゲーションバー分を加算
final bottomInset = MediaQuery.viewPaddingOf(context).bottom;
ListView(
padding: EdgeInsets.only(bottom: 16 + bottomInset),
children: [ /* ... */ ],
);
- 画面 body は
SafeArea(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 警告は、フレームワーク由来で実害がないケースがある。出どころを確認し、アプリ側の緊急対応が要るのかを見極めるのが大事です。