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:
- 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.
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;
}