Reactライクにクロスプラットフォームなアプリがかけるところに魅力を感じ最近はFlutterの勉強をしている。
ボタンが押されたときとかにスナックバーを出したい。 MaterialAppのScaffoldを使っているのであればScaffoldMessengerというものを使えば良い。 具体的には下記のような感じ。
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text("fabbed!"),
));
ビルドコンテキストで一番近い親のScaffoldMessengerに対してスナックバーを出す指示を送る感じ。
なので、注意点としてはScaffoldMessenger.of(context)
が実行されたウィジェットより上の階層でScaffoldMessengerがいないとエラーになるということ。
下記のサンプルコードではスナックバーを表示するロジックをHomeというウィジェット内で実行しており、そのウィジェットをMyAppというウィジェットで使っている。そのためHomeからみると親としてMyApp内でScaffoldMessengerが定義されているので (正確にはMaterialApp)、ScaffoldMessengerを見つけることができる。
一方でもしHomeに切り出さずMyApp内でスナックバー表示ロジックを実行すると、MyAppより上の階層にはScaffoldMessengerはいないのでエラーになる。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
appBarTheme: const AppBarTheme(backgroundColor: Colors.amber)),
debugShowCheckedModeBanner: true,
home: const Home(),
);
}
}
class Home extends StatelessWidget {
const Home({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => _showToast(context),
child: const Icon(Icons.ac_unit)),
appBar: AppBar(centerTitle: true, title: const Text("hoge")),
body: const Center(child: Text("hello world!")));
}
void _showToast(BuildContext context) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text("fabbed!"),
));
}
}