🦄
【Flutter】SnackBarを上に表示したい
結論
私ごときの技術力では分かりませんでした。[完]
別の何かしらがないかなぁと調べていたら、MaterialBannerというものを見つけました。
パッと見た感じ「これでええやん!」と思って、試しに使ってみようと思いました。
popしたら逝った
SnackBar
みたいに自動で消すようにもしておきたいなぁと思って、無理だろうとは感じながら、こんな感じに記載しました。
onVisible: () {
Future.delayed(const Duration(seconds: 3), () {
ScaffoldMessenger.of(context).removeCurrentMaterialBanner(); });
},
無事にpopしたら逝きました。
いつまで経っても消えることはありませんでした。
対応
エントリポイントの部分MaterialApp.router
にkey
を挿せるので、グローバルに使用できるようにProviderを作成しました(Providerにしなくてもいい)。
(keepAlive: true)
GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey(
ScaffoldMessengerKeyRef ref) =>
GlobalKey<ScaffoldMessengerState>();
で、これを挿す。
MaterialApp.router({
scaffoldMessengerKey: ref.watch(scaffoldMessengerKeyProvider),
// ry
});
MaterialBanner
を使う側はこんな感じ。
final key = ref.watch(scaffoldMessengerKeyProvider);
key.currentState?.showMaterialBanner(
MaterialBanner(
margin: const EdgeInsets.all(10),
elevation: 1,
leading: const Icon(Icons.check),
content: const Text('Successed'),
actions: [
TextButton(
child: Text('close'),
onPressed: () => key.currentState?.removeCurrentMaterialBanner(),
),
],
onVisible: () {
Future.delayed(
const Duration(seconds: 3),
() => key.currentState?.removeCurrentMaterialBanner(),
);
},
),
);
これはpopさせてないけど、見た目はこんな感じになる。
上に出てきてくれるSnackBar
っぽいものは実現できる。
余談
elevationというプロパティがあるんですが、デフォルトでは0
になっています。
ドキュメント読んで分かったんですが、これがデフォルトのままだと、バナーの大きさだけ、下にBodyが押し出されます(消えたら戻ります)。
ここの動きは好みだと思うので、押し出されるのが嫌な場合はプロパティをいじってみてください。
Discussion