0
1

【Flutter】MediaQueryでpaddingが0になる時の対処法

Last updated at Posted at 2024-06-26

MediaQueryDataのpaddingプロパティを使って、ノッチ部分やステータスバーなどの高さなどを取得できます。
https://api.flutter.dev/flutter/widgets/MediaQueryData/padding.html
ただし、この値はMediaQueryのremovePaddingコンストラクタによってremoveすることができます。

iphone 15 ProMaxでの検証です。

media_query_test.dart
    return Builder(
      builder: (context) {
        print(MediaQuery.of(context).padding.top); // 59
        return Scaffold(
          body: MediaQuery.removePadding(
            context: context,
            removeTop: true,
            child: Builder(builder: (context) {
              print(MediaQuery.of(context).padding.top); // 0
              return const SizedBox();
            }),
          ),
        );
      },
    );

このremovePaddingはAppBarやSafeAreaなどを使用した時に使われます。

scaffold.dart
  void _addIfNonNull(
    List<LayoutId> children,
    Widget? child,
    Object childId, {
    required bool removeLeftPadding,
    required bool removeTopPadding, // Scaffoldのappbarプロパティがnullでない時にtrue
    required bool removeRightPadding,
    required bool removeBottomPadding,
    bool removeBottomInset = false,
    bool maintainBottomViewPadding = false,
  }) {
    MediaQueryData data = MediaQuery.of(context).removePadding(
      removeLeft: removeLeftPadding,
      removeTop: removeTopPadding,
      removeRight: removeRightPadding,
      removeBottom: removeBottomPadding,
    );
    // 割愛
  }

よって、AppBarを設定している場合は、Scafolldの子Widgetでは以下のようになります。

media_query_test.dart
    return Builder(
      builder: (context) {
        print(MediaQuery.of(context).padding.top); // 59
        return Scaffold(
          appBar: AppBar(),
          body: Builder(builder: (context) {
            print(MediaQuery.of(context).padding.top); // 0
            return const SizedBox();
          }),
        );
      },
    );

ではもし、appbarを指定したScaffoldやSafeAreaの子Widget内で値を取得したい場合はどうすれば良いでしょうか。

1. 親が取得したpaddingを子Widget内で使用する。

media_query_test.dart
    return Builder(
      builder: (context) {
        final topPadding = MediaQuery.of(context).padding.top;
        print(topPadding); // 59
        return Scaffold(
          appBar: AppBar(),
          body: Builder(builder: (context) {
            print(topPadding); // 59
            return const SizedBox();
          }),
        );
      },
    );

2.MediaQueryDataのfromViewコンストラクタを使用する。
https://api.flutter.dev/flutter/widgets/MediaQueryData/MediaQueryData.fromView.html

media_query_test.dart
    return Builder(
      builder: (context) {
        print(MediaQuery.of(context).padding.top); // 59
        return Scaffold(
          appBar: AppBar(),
          body: Builder(builder: (context) {
            print(MediaQueryData.fromView(View.of(context)).padding.top); // 59
            return const SizedBox();
          }),
        );
      },
    );

1.のやり方だとネストが深くなると大変なところもありますが、2.のやり方だとどこからでもアクセスできるのがメリットかなと思います。

最後に

記事を読んで頂きありがとうございました!今回初めて記事を書いてみました。今までは自分の記事など需要があるのかと思っていましたが、ないよりはあった方がいいだろうと考え投稿させて頂きました。

この記事に関しての技術的な指摘はもちろん、記事の書き方について、またはこの記事にかかわらず皆様が記事を書く上で気をつけていることや、初心者の内に知ってればよかったことなどコメント頂けると助かります🙇‍♂️

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1