概要
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;
端末ごとの画面上部の高さはこのようにして取得できます。
良い感じの解決策は現在調査中です・・。
参考