Show SnackBar in Flutter

I want to display a simple SnackBar inside a stateful flutter . My application creates a new instance of MaterialApp with widgets with the MyHomePage state.

I am trying to show the SnackBar method in the showSnackBar () method. But it fails with the "showSnackBar method" was called on null.

What is wrong with this code?

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new MyHomePage(), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key}) : super(key: key); @override _MyHomePageState createState() => new _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); @override void initState() { super.initState(); showInSnackBar("Some text"); } @override Widget build(BuildContext context) { return new Padding( key: _scaffoldKey, padding: const EdgeInsets.all(16.0), child: new Text("Simple Text") ); } void showInSnackBar(String value) { _scaffoldKey.currentState.showSnackBar(new SnackBar( content: new Text(value) )); } } 

DECISION:

 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new Scaffold(body: new MyHomePage()), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key}) : super(key: key); @override _MyHomePageState createState() => new _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { showInSnackBar("Some text"); return new Padding( padding: const EdgeInsets.all(16.0), child: new Scaffold( body: new Text("Simple Text") ) ); } void showInSnackBar(String value) { Scaffold.of(context).showSnackBar(new SnackBar( content: new Text(value) )); } } 
+27
source share
9 answers

There are three problems. First, you don’t have a forest anywhere, and the Scaffold widget is the one who knows how to display snacks. Secondly, you have a key to capture the scaffold, but instead you put it on Padding (and Paddings are not aware of snacks). Thirdly, you used the key before the widget with which it was associated was able to initialize, since initState is called before assembly.

The easiest solution is to change the home line in MyApp widgets to:

home: new Scaffold(body: new MyHomePage()),

... and then remove all references to _scaffoldKey and use Scaffold.of(context) instead, where you have _scaffoldKey.currentState .

+30
source

In my case, I had this code (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 did not set up the key for the scaffold. so when i add the key: _scaffoldKey

  @override Widget build(BuildContext context) { return new Scaffold( key: _scaffoldKey, body: new SafeArea( 

the diner starts to work :)

+17
source

There is a better and cleaner way to display a fluttering snack bar. I found this the hard way and sharing, so maybe this is useful for someone else.

No need to change in the main part of the application

 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'MyApp', theme: new ThemeData( primarySwatch: Colors.orange), home: new MainPage()); } } 

The page status code is where everything will change.

We know that Flutter provides Scaffold.of(context).showSnackBar . However, the context should be the context of the descendant of the scaffold, and not the context of the scaffold. To avoid errors, we need to use the BuildContext for the Scaffold body and save it in a variable, as shown 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 in the world and it will display a snack bar. For example, I use it to display internet connection messages.

+10
source

I do it, work for me :)

 @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text('Demo') ), body: new Builder( // Create an inner BuildContext so that the onPressed methods // can refer to the Scaffold with Scaffold.of(). builder: (BuildContext context) { return new Center( child: new RaisedButton( child: new Text('SHOW A SNACKBAR'), onPressed: () { Scaffold.of(context).showSnackBar(new SnackBar( content: new Text('Hello!'), )); }, ), ); }, ), ); } 
+5
source

initState is called before build I think _scaffoldKey.currentState not initialized when it is a call.

I do not know if you can get ScaffoldState from initState . If you change your code, you can show the snackbar from build with:

 Scaffold.of(context).showSnackBar(new SnackBar(new Text(value))); 
+3
source

In case someone wants to initialize Snackbar in initState() (in other words, when the page loads, here is my solution). Also, I assume you already have _scaffoldKey .

 void initState() { super.initState(); Future.delayed(Duration(seconds: 1)).then( (_) => _displaySnackbar ); } // Display Snackbar void get _displaySnackbar { _scaffoldKey.currentState.showSnackBar(SnackBar( duration: Duration(minutes: 1), content: Text('Your snackbar message') )); } 
+2
source

To initialize Snackbar in initState (), you can execute the function after building the layout.

 void initState() { super.initState(); WidgetsBinding.instance .addPostFrameCallback((_) => _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Your message here..")));} 
+1
source
 Scaffold.of(context).showSnackBar( SnackBar(content: Text("Thanks for using snackbar", textAlign: TextAlign.center, style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold),), duration: Duration(seconds: 2), backgroundColor: Colors.red,) ); 
+1
source

You can use this:

 final _scaffoldKey = GlobalKey<ScaffoldState>(); @override Widget build(BuildContext context) { return Scaffold( key: _scaffoldKey, appBar: AppBar( ), } } 

and then in onPressed() you can add this code

 _scaffoldKey.currentState.showSnackBar( new SnackBar( content: new Text('Hello this is snackbar!') ) ); 
0
source

Source: https://habr.com/ru/post/1012291/


All Articles