While looking for examples for using flutter SnackBar with ScaffoldMessenger, I only found usages with onPressed function:

    Widget build(BuildContext context) {
        return Container(
            child: ElevatedButton(
              child: ...,
              onPressed: () => _showToast(context),
            ));
      }

      void _showToast(BuildContext context) {
        final scaffold = ScaffoldMessenger.of(context);
        scaffold.showSnackBar(
          SnackBar(content: const Text('Added to favorite')),
        );
      }
    }

but non of the examples explain why one have to use it with onPressed only, so I tried it my self and used in directly inside the build function:

         Widget build(BuildContext context) {
           _showToast(context);   <---
           return Container(
              child: ElevatedButton(
                ...,
            ));
      }

but than I got this error:

enter image description here

and I am not sure why this it happening.

I ended up giving Scaffold a key and using the GlobalKey<ScaffoldState> approach, but I really want to understand why using ScaffoldMessenger.of(context).showSnackBar() without a callback\onPressed didn't work


Solution 1: Ravindra S. Patil

Try to add or declare your snackbar inside Future.deleayd

Future.delayed(Duration.zero, () async {
                  yourSnackBarFunction();
                });


Solution 2: Peter Koltai

In Flutter build function is called by the framework itself whenever a widget needs to be rebuilt. It can occur many times!

On the other hand, you usually want to display a toast / snackbar when you want to inform your user about something. So you can display a snackbar from onPressed and many other places, but the build function itself is only for building a widget, and not responding directly to user actions.


Solution 3: Yeasin Sheikh

while ScaffoldMessenger.of(context) we need to give some time to be rendered properly(for full Scaffold). we can know the time from addPostFrameCallback. Also if you try to show the middle of widgets, the 1st portion will render but rest widgets will face this issue.

here is the soulution on build method.

  WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
      _showToast(context);
    });

to understand the concept properly we can do something like this.

Scaffold(
      body: Container(
        height: 100,
        color: Colors.cyanAccent,
        child: Column(
          children: [
            Text("This text will render "),
            Builder(builder: (context) {
              _showToast(context);

              ///but you will be able to see Message
              return Text("it will cause error");
            }),
            Text("This text will not render "),
          ],
        ),
      ),
    );