毎日Flutter生活 Advent Calendar 2025 の10日目です![]()
こんにちは!tatata-keshiです![]()
今回はSafeAreaウィジェットを用いてヘッダーと他の要素が重ならないようにする方法についてまとめました。
この記事はFlutter歴約1週間の人が書いています!間違ったことを記載していても寛大な心で教えていただけると幸いです![]()
1. ヘッダーと他の要素が重なってしまう
そもそもSafeAreaについて調べるきっかけになったのは、CupertinoScaffoldを使用してアプリUIを実装しようとした際にヘッダーと他の要素が重なってしまったからです。
この画像のように「Test Appと書かれたヘッダーの下に青いボタンが隠れてしまっています。
以下が実際のコードです。
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(middle: Text(widget.title)),
child: Column(
children: <Widget>[
Center(child: Text('このボタンが表示されるかな?')),
const SizedBox(height: 20.0),
Center(
child: CupertinoButton.filled(
onPressed: () => print('hoge'),
child: const Icon(CupertinoIcons.add),
),
),
],
),
);
}
今回の実装ではページの大枠にCupertinoPageScaffoldを用いました。このウィジェットが持つプロパティの中にはnavigationBarとchildがあり、それぞれヘッダー要素とそれ以外のメインの要素という理解でした。
自分の中のイメージではMaterialAppのScaffoldウィジェットにおけるappBarとbodyの関係と同じものだったため、navigationBar要素とchild要素が重なるのは予想外でした。
2. navigationBarとchildが重ならないようにする方法
navigationBarに設定したウィジェットとchildに設定したウィジェットが重ならないようにするには、SafeAreaウィジェットを使用します。
以下のように変更します。
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(middle: Text(widget.title)),
// SafeAreaで囲む
child: SafeArea(
child: Column(
children: <Widget>[
Center(child: Text('このボタンが表示されるかな?')),
const SizedBox(height: 20.0),
Center(
child: CupertinoButton.filled(
onPressed: () => print('hoge'),
child: const Icon(CupertinoIcons.add),
),
),
],
),
),
);
}
このようにnavigationBarと重なっていたchild要素をSafeAreaウィジェットで囲うことによってヘッダーとそれ以外の要素が重ならないようになります。
3. SafeAreaウィジェットは何者なの?
ヘッダーとそれ以外の要素を重ならないようにすることはできましたが。しかし、このSafeAreaは何者なのでしょうか?
公式ドキュメントの説明では、画面上部に表示されるノッチや下部の表示されるホームバー、通知といった要素とアプリの画面が重なるのを回避するためのウィジェットのようです。
そして実装例のコードにあるようにappBarがある場合はappBarの箇所を除いた画面がSafeAreaとして扱われるようになっているみたいですね。
まとめ
このようにSafeAreaウィジェットを用いることでヘッダーとそれ以外の画面要素が重なるのを防ぐことができます。
またこのウィジェットはノッチやホームバーとアプリケーションの画面が重なるのも回避させる役割があるため、ユーザビリティを確保するためには必須級のウィジェットのようですね。

