of static method

The state from the closest instance of this class that encloses the given context.

Typical usage of the ScaffoldMessenger.of function is to call it in response to a user gesture or an application state change.

To see it in action, copy and run this code snippet on DartPad.

import 'package:material_ui/material_ui.dart';

/// Flutter code sample for [ScaffoldMessenger.of].

void main() => runApp(const OfExampleApp());

class OfExampleApp extends StatelessWidget {
  const OfExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('ScaffoldMessenger.of Sample')),
        body: const Center(child: OfExample()),
      ),
    );
  }
}

class OfExample extends StatelessWidget {
  const OfExample({super.key});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      child: const Text('SHOW A SNACKBAR'),
      onPressed: () {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('Have a snack!')));
      },
    );
  }
}

A less elegant but more expedient solution is to assign a GlobalKey to the ScaffoldMessenger, then use the key.currentState property to obtain the ScaffoldMessengerState rather than using the ScaffoldMessenger.of function. The MaterialApp.scaffoldMessengerKey refers to the root ScaffoldMessenger that is provided by default.

Sometimes SnackBars are produced by code that doesn't have ready access to a valid BuildContext. One such example of this is when you show a SnackBar from a method outside of the build function. In these cases, you can assign a GlobalKey to the ScaffoldMessenger. This example shows a key being used to obtain the ScaffoldMessengerState provided by the MaterialApp.

To see it in action, copy and run this code snippet on DartPad.

import 'package:material_ui/material_ui.dart';

/// Flutter code sample for [ScaffoldMessenger.of].

void main() => runApp(const OfExampleApp());

class OfExampleApp extends StatefulWidget {
  const OfExampleApp({super.key});

  @override
  State<OfExampleApp> createState() => _OfExampleAppState();
}

class _OfExampleAppState extends State<OfExampleApp> {
  final GlobalKey<ScaffoldMessengerState> _scaffoldMessengerKey =
      GlobalKey<ScaffoldMessengerState>();
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
    if (_counter % 10 == 0) {
      _scaffoldMessengerKey.currentState!.showSnackBar(
        const SnackBar(content: Text('A multiple of ten!')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      scaffoldMessengerKey: _scaffoldMessengerKey,
      home: Scaffold(
        appBar: AppBar(title: const Text('ScaffoldMessenger Demo')),
        body: Center(
          child: Column(
            mainAxisAlignment: .center,
            children: <Widget>[
              const Text('You have pushed the button this many times:'),
              Text(
                '$_counter',
                style: Theme.of(context).textTheme.headlineMedium,
              ),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}

If there is no ScaffoldMessenger in scope, then this will assert in debug mode, and throw an exception in release mode.

See also:

Implementation

// TODO(framework): Replace the following block with a @dartpad directive
// when it's supported. https://github.com/dart-lang/dartdoc/issues/4123
/// {@macro material_ui.dartpad_guide}
///
/// {@example /example/lib/scaffold/scaffold_messenger.of.0.dart#body}
///
/// </callout-box>
///
/// A less elegant but more expedient solution is to assign a [GlobalKey] to the
/// [ScaffoldMessenger], then use the `key.currentState` property to obtain the
/// [ScaffoldMessengerState] rather than using the [ScaffoldMessenger.of]
/// function. The [MaterialApp.scaffoldMessengerKey] refers to the root
/// ScaffoldMessenger that is provided by default.
///
/// <callout-box>
///
/// Sometimes [SnackBar]s are produced by code that doesn't have ready access
/// to a valid [BuildContext]. One such example of this is when you show a
/// SnackBar from a method outside of the `build` function. In these
/// cases, you can assign a [GlobalKey] to the [ScaffoldMessenger]. This
/// example shows a key being used to obtain the [ScaffoldMessengerState]
/// provided by the [MaterialApp].
///
// TODO(framework): Replace the following block with a @dartpad directive
// when it's supported. https://github.com/dart-lang/dartdoc/issues/4123
/// {@macro material_ui.dartpad_guide}
///
/// {@example /example/lib/scaffold/scaffold_messenger.of.1.dart#body}
///
/// </callout-box>
///
/// If there is no [ScaffoldMessenger] in scope, then this will assert in
/// debug mode, and throw an exception in release mode.
///
/// See also:
///
///  * [maybeOf], which is a similar function but will return null instead of
///    throwing if there is no [ScaffoldMessenger] ancestor.
///  * [debugCheckHasScaffoldMessenger], which asserts that the given context
///    has a [ScaffoldMessenger] ancestor.
static ScaffoldMessengerState of(BuildContext context) {
  assert(debugCheckHasScaffoldMessenger(context));

  final _ScaffoldMessengerScope scope = context
      .dependOnInheritedWidgetOfExactType<_ScaffoldMessengerScope>()!;
  return scope._scaffoldMessengerState;
}