Display SnackBar in Flutter
In my case i had code like this (in class state)
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
void showInSnackBar(String value) {
_scaffoldKey.currentState.showSnackBar(new SnackBar(content: new Text(value)));
}
but i didn't setup the key for scaffold. so when i add key: _scaffoldKey
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
body: new SafeArea(
snackbar start to work :)
There's a better and cleaner way to display a Snackbar in flutter. I found it the hard way and sharing so that maybe it's helpful for someone else.
No need to change in your main app part
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'MyApp',
theme: new ThemeData(
primarySwatch: Colors.orange),
home: new MainPage());
}
}
Page State code is where things will change.
We know Flutter provides Scaffold.of(context).showSnackBar
. However, the context should be the context of a descendant of a Scaffold, and not the context that includes a Scaffold. In order to avoid error, we need to use a BuildContext for the body of the Scaffold, and store it in a variable, as below.
class MainPageState extends State<MainPage> {
BuildContext scaffoldContext;
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.grey,
appBar: new AppBar(
title: const Text(APP_TITLE),
),
body: new Builder(builder: (BuildContext context) {
scaffoldContext = context;
return new Center(
child: new Text('Hello World', style: new TextStyle(fontSize: 32.0)),
);
}));
}
void createSnackBar(String message) {
final snackBar = new SnackBar(content: new Text(message),
backgroundColor: Colors.red);
// Find the Scaffold in the Widget tree and use it to show a SnackBar!
Scaffold.of(scaffoldContext).showSnackBar(snackBar);
}
}
Now, you can call this function from anywhere and it will display the Snackbar. For example, I am using it to display Internet Connectivity messages.
There's three problems. The first is that you don't have a Scaffold anywhere, and the Scaffold widget is the one that knows how to show snack bars. The second is that you have a key for getting a hold of the scaffold, but you've put it on a Padding instead (and Paddings don't have any knowledge of snack bars). The third is that you've used the key before the widget that it's associated with has had a chance to be initialised, since initState is called before build.
The simplest solution is to change the home
line in your MyApp widget to:
home: new Scaffold(body: new MyHomePage()),
...and then remove all mention of _scaffoldKey
and instead use Scaffold.of(context)
where you currently have _scaffoldKey.currentState
.
ScaffoldState
is now deprecated. Use ScaffoldMessengerState
.
There are generally two ways of showing the SnackBar
using ScaffoldMessenger
.
Direct way:
@override Widget build(BuildContext context) { return Scaffold( body: ElevatedButton( onPressed: () { var snackBar = SnackBar(content: Text('Hello World')); ScaffoldMessenger.of(context).showSnackBar(snackBar); }, child: Text('Show SnackBar'), ), ); }
Using
GlobalKey
.final _globalKey = GlobalKey<ScaffoldMessengerState>(); @override Widget build(BuildContext context) { return ScaffoldMessenger( key: _globalKey, child: Scaffold( body: Center( child: ElevatedButton( onPressed: () { var snackBar = SnackBar(content: Text('Hello World')); _globalKey.currentState.showSnackBar(snackBar); }, child: Text('Show SnackBar'), ), ), ), ); }