※追記!!!!
当初載せていたコードからシンプルなものに変更しました。
本文
flutterにある便利なWidgetの一つがDialog。SimpleDialogとかAlertDialogとか色々あります。気軽に使えて、かつ表示内容も凝ったものにできるので、とても助かるのですが今回、「表示内容を更新できない」という問題に遭遇しました。
これはsetState()でも発生しますし、ChangeNotifier&Providerパターンでも発生してしまいます。というのもこれらはstatelessなのでどうしようもないものだそうで。自分は内部まで詳しく知らないのであれですが。
この現象により、DropDownを表示しても選択したものに切り替わらなかったのが自分がぶつかった部分でした。
今回、回避策を見つけたので紹介します。ちなみに私は「ChangeNotifer&Providerパターンで実装している画面での表示」を目標としています。
回避策
showDialog()ではなく、showGeneralDialogを使います。
※正しいパターン
showGeneralDialog(
barrierColor: Colors.black.withOpacity(0.3),
transitionDuration: Duration(milliseconds: 100),
barrierDismissible: true,
barrierLabel: '',
context: context,
pageBuilder: (context, animation1, animation2) {
return DefaultTextStyle(
style: Theme.of(context).primaryTextTheme.bodyText1!,
child:Center(
child: Container(
height: 300,
width: 300,
color: Colors.white,
child: SingleChildScrollView(child: Text('コンテンツ')),
),
),
);
},
);
Containerが表示している部分のサイズを指定してます。ここが表示されるWidgetのベースになるイメージ。
このコードには書いてませんが、DropDownで選択したものもうまく表示される様になりましたし、FutureBuilderも問題なしです。
また、ShowGeneralDialogを使うとデフォルトのスタイルが設定されているツリーからは外れてしまうため、そのままだと表示が乱れたTextになってしまいます。なので、DefaultTextStyleを使うことでデフォルトと同じTextが表示されるようにしています。
注意
大概の表示は問題なくできたのですが、子WidgetにExpandを使ったDialogを実装すると、「シミュレータでは問題ないが、実機もしくはリリースビルドで表示されなくなる(領域がグレーで塗りつぶされる)」という現象が発生しました。色々試しましたが原因はわかりません、。とりあえずExpandを使わないとうまくいきました。もし原因不明のエラーが発生した場合は、Expandを使っていないか確かめてみましょう。
まとめ
このExpandを使うと表示されなくなる現象は調べても出てこなかったので、バージョン依存によるものかもしれません。ただどちらにしろ、今回のような特殊な組み方をしている場合は、実機デバッグの必要性もあるのだなあと感じる出来事でした。