LoginSignup
3
1

More than 1 year has passed since last update.

【Flutter】showModalBottomSheetでSafeAreaが効かない時の対処法

Last updated at Posted at 2021-09-08

概要

FlutterでモバイルアプリのUI実装をする際、isScrollControlledをtrueにしたModalBottomSheetが画面上部の網掛け部分にかかってしまう問題の解消法をご紹介いたします。

使用するWidget

親Widget(お問い合わせフォーム) - main.dart

子Widget(メッセージ送信フォーム)- child.dart

画面上部の網掛け部分にViewが被ってしまっていますね・・。
AppBarが無いViewではSafeAreaを使うことで、画面上部に被らないように実装できるはずなのですが・・

childView.dart

  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea( //SafeAreaを使えば画面上部に被るのを防止できるはず・・
        child: Container(...),
      )
    );
  }

残念ながら変わりません・・。

解決策

main.dart

// --省略
child: ElevatedButton(
  child: Text("お問い合わせをする"),
  onPressed: () {
    BuildContext mainContext = context; //これを追加
    showModalBottomSheet(
    context: context,
    isScrollControlled: true,
    builder: (BuildContext context) {
      return parentWidget(
        mainContext //子Widgetに渡す
      );
    });
  },
),
childView.dart
Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          margin: EdgeInsets.all(20),
          padding: EdgeInsets.only( //
            top: MediaQuery.of(widget.context).padding.top, //親Widgetから渡されたBuildContextをpaddingで指定
          ),
          child: Column(//..省略),
        ),
      ),
    );
  }

無事いい感じに表示されました。

問題点

親Widgetがmain.dartじゃない場合、子WidgetにBuildContextを渡してpaddingに指定しても0.0として扱われ、正しく対処できない。

→ main.dartでMediaQueryを使って画面上部のpaddingを取得し、子Widgetまで渡してpaddingで指定すれば良い?

main.dart
double height = MediaQuery.of(context).padding.top;

端末ごとの画面上部の高さはこのようにして取得できます。
良い感じの解決策は現在調査中です・・。

参考

3
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
3
1