Hasan A Yousef
Hasan A Yousef

Reputation: 25008

Error getting show SnackBar AT STARTUP

I wrote this code, to get a [SnakBar][1] after widget load:

@override
initState(){
  super.initState();
        Scaffold.of(_scaffoldContext).showSnackBar(new SnackBar(
        content: new Text("TGPS & SMS Permissions are required"),
      ));
} 

But I got this error:

Scaffold.of() called with a context that does not contain a Scaffold.

I read this article, but did not understand how to use it.

Upvotes: 0

Views: 991

Answers (2)

Shady Aziza
Shady Aziza

Reputation: 53347

It is better to add a key to your Scaffold and call key.currentState.showSnackBar.

Now in order to handle this once the widget build itself you actually need to hold on for a second to get the required context. Hence I wrap my _buildSnackBar method within a Future.delayed call to make sure the build method got called before the _buildSnackBar one.

So what you need to do is something similar to this example:

class SnackBarExample extends StatefulWidget {
  @override
  _SnackBarExampleState createState() => new _SnackBarExampleState();
}

class _SnackBarExampleState extends State<SnackBarExample> {
 GlobalKey<ScaffoldState> key= new GlobalKey<ScaffoldState>();
 @override
 void initState() {
      new Future.delayed(const Duration(seconds: 1))
      .then((_)=>_buildSnackBar()
      );
     super.initState();
   }
   _buildSnackBar (){

     key.currentState.showSnackBar(
       new SnackBar(
         content: new Text("I am your snack bar"),
       )
     );
   }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      key:key,
    );
  }
}

Upvotes: 2

Jonah Williams
Jonah Williams

Reputation: 21451

The method Scaffold.of uses the provided context to look for a parent widget which is a Scaffold. If that can't be found, then you will get the error above. Here is an example of how that can happen, and how to fix it.

For example, below it looks like we have a scaffold in the tree right? But the context getter in initState points to the current location in the widget tree, of which Scaffold is actually a child

class MyHomePageState extends State<MyHomePage> {
 @override
 void initState() {
   super.initState():
   Scaffold.of(context);
 }

 Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        body: new Text('foo'),
      ),
    );
  }
}

The widget tree looks something like this:

MyHomePage <- MaterialApp <- Scaffold <- Text

Instead, what you should do is create a widget that is a child of the scaffold. Leaving MyHomePageState as it is, except for removing Scaffold.of, replace the body with another Stateful widget.

class MyBodyState extends State<MyBody> {
  void initState() {
    super.initState();
    Scaffold.of(context);
  }

  Widget build(BuildContext context) => ...
}

Now your widget tree looks like this:

MyHomePage <- MaterialApp <- Scaffold <- MyBody <- Text

Since the MyBody widget is a child of the Scaffold, Scaffold.of should be able to find a Scaffold instance.

Upvotes: 1

Related Questions