Flutter: Showing SnackBar within the Widget that builds a Scaffold

Katarina Sheremet
Jul 16, 2018 · 3 min read

Sometimes you need to implement a simple logic that shows SnackBar. Let’s imagine there is a Button that shows a SnackBar.

After pushing the Button you can see the following error:

Scaffold.of() called with a context that does not contain a Scaffold. No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This usually happens when the context provided is from the same StatefulWidget as that whose build function actually creates the Scaffold widget being sought. There are several ways to avoid this problem. The simplest is to use a Builder to get a context that is “under” the Scaffold. For an example of this, please see the documentation for Scaffold.of(): https://docs.flutter.io/flutter/material/Scaffold/of.html
A more efficient solution is to split your build function into several widgets. This introduces a new context from which you can obtain the Scaffold. In this solution, you would have an outer widget that creates the Scaffold populated by instances of your new inner widgets, and then in these inner widgets you would use Scaffold.of(). A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the key.currentState property to obtain the ScaffoldState rather than using the Scaffold.of() function. The context used was …

It happens because the current context doesn’t contain a Scaffold. Even though we see that our build function returns Scaffold. Context starts to look for a Scaffold in the parent and the current build function is dismissed.

Let’s implement all suggested techniques to fix the problem (from the screenshot above).

Builder Widget

We start by wrapping the Button with a Builder Widget. It is a platonic Widget that calls a closure to obtain its child widget. To display the SnackBar it uses a context from Builder.

Split a build function

The next suggested approach is to split a build function into several widgets. That’s why we move our Button to a StatelessWidget.

The build function has a child context and our SnackBar displays successfully.

Global Key

The last recommended approach is to assign a GlobalKey to the Scaffold. A key that is unique across the entire app. Global keys uniquely identify elements, provide access to other objects that are associated with elements, such as a BuildContext and, for StatefulWidgets, a State. Global keys are expensive, and, in my opinion, it is not a good approach to solve this problem if there are another two approaches that are described above. But anyway let’s have a look at how to implement this. We need to create a Global key instance and assign it to the Scaffold Widget:

After that we will get a state of Scaffold to show SnackBar:

Resources:


Katarina Sheremet

Written by

Google Developer Expert in Flutter and Dart

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade