Revisiting Displaying a SnackBar in a Dialog with SnackBarMessenger

Photo by Mohammad Rahmani / Unsplash

In a previous article we looked at the surprisingly non-trivial way to display a SnackBar from within a Dialog context in Flutter.

The full article gives additional context but  the TLDR was:

  • A Scaffold context is required to display a SnackBar
  • Dialogs appear outside of Scaffold contexts
  • Wrap the Dialog with a Scaffold and handle the gesture to close edge cases
Displaying a Snackbar in a Dialog with Flutter
A Flutter tutorial where we add a Snackbar to a Dialog

Flutter 2.0 introduced ScaffoldMessenger as a replacement for displaying SnackBars directly from the Scaffold class. The main use case it seems to be trying to solve is synchronizing a SnackBar across navigation events. You can see this in action if you position two Scaffolds on the same page and dispatch a SnackBar from one of them:

When watching the Flutter Widget of the Week on ScaffoldMessenger I was excited to see that it sits above all Scaffolds in the hierarchy and came built into the MaterialApp widget.

Credit: Flutter YouTube Channel

Perhaps this was the solution to the SnackBar in a Dialog problem? To save ourselves some time, unfortunately, it wasn't. 😭

Despite that there are some notable differences that we can take a look at, and our final solution is a bit more streamlined.

Revised Solution

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          child: const Text("Show Dialog"),
          onPressed: () {
            showDialog(
              useSafeArea: false,
              context: context,
              builder: (context) => Stack(
                children: [
                  const IgnorePointer(
                    child: Scaffold(
                      backgroundColor: Colors.transparent,
                    ),
                  ),
                  SafeArea(
                    child: AlertDialog(
                      title: const Text("SnackBar Dialog"),
                      content: ElevatedButton(
                        child: const Text("Show SnackBar"),
                        onPressed: () {
                          ScaffoldMessenger.of(context).showSnackBar(
                            const SnackBar(
                              content: Text("Hello, SnackBar!"),
                            ),
                          );
                        },
                      ),
                    ),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}

The full code is available on my GitHub. Major changes from the previous solution are broken down below

GitHub - MagsMagnoli/flutter-scaffold-messenger: A demonstration of displaying snackbars inside of a modal using ScaffoldMessenger
A demonstration of displaying snackbars inside of a modal using ScaffoldMessenger - GitHub - MagsMagnoli/flutter-scaffold-messenger: A demonstration of displaying snackbars inside of a modal using ...

No More Gesture Detectors

By wrapping the Dialog with a Scaffold we needed to introduce GestureDetectors to handle touch events on the Dialog backdrop. With ScaffoldMessenger we no longer need the Scaffold to be a direct parent of the AlertDialog and using a Stack widget allows us to place the  outside of the Dialog widget tree. This allows us to leverage the IgnorePointer widget instead of GestureDetector.

No More Errors

In the previous article, calling Scaffold.of in the Dialog threw an error and required us to wrap it with a Scaffold. With ScaffoldMessenger.of we no longer throw an error but now display a SnackBar in the Scaffold underneath it.

Caveat: SafeArea

The showDialog function wraps its content with a SafeArea widget by default. This causes SnackBars to be displayed above the bottom edge of the device. To fix this issue disable the useSafeArea flag on the showDialog function then wrap the AlertDialog with a SafeArea manually.

Wrapping Up

Thanks for reading! If you enjoyed this article, please consider sharing it with others and becoming a sponsor on GitHub. ❤️

Mags
Founder of Mags.ai. Building an open community of motivated learners