showSnackBar method Null safety
- SnackBar snackBar
Shows a SnackBar
across all registered Scaffolds.
A scaffold can show at most one snack bar at a time. If this function is called while another snack bar is already visible, the given snack bar will be added to a queue and displayed after the earlier snack bars have closed.
To control how long a SnackBar
remains visible, use SnackBar.duration.
To remove the SnackBar
with an exit animation, use hideCurrentSnackBar
or call ScaffoldFeatureController.close on the returned
ScaffoldFeatureController. To remove a SnackBar
suddenly (without an
animation), use removeCurrentSnackBar.
See ScaffoldMessenger.of for information about how to obtain the ScaffoldMessengerState.
Here is an example of showing a
SnackBar
when the user presses a button.
To create a local project with this code sample, run:
flutter create --sample=material.ScaffoldMessengerState.showSnackBar.1 mysample
flutter create --sample=material.ScaffoldMessengerState.showSnackBar.1 mysample
Implementation
ScaffoldFeatureController<SnackBar, SnackBarClosedReason> showSnackBar(SnackBar snackBar) {
assert(
_scaffolds.isNotEmpty,
'ScaffoldMessenger.showSnackBar was called, but there are currently no '
'descendant Scaffolds to present to.',
);
_snackBarController ??= SnackBar.createAnimationController(vsync: this)
..addStatusListener(_handleSnackBarStatusChanged);
if (_snackBars.isEmpty) {
assert(_snackBarController!.isDismissed);
_snackBarController!.forward();
}
late ScaffoldFeatureController<SnackBar, SnackBarClosedReason> controller;
controller = ScaffoldFeatureController<SnackBar, SnackBarClosedReason>._(
// We provide a fallback key so that if back-to-back snackbars happen to
// match in structure, material ink splashes and highlights don't survive
// from one to the next.
snackBar.withAnimation(_snackBarController!, fallbackKey: UniqueKey()),
Completer<SnackBarClosedReason>(),
() {
assert(_snackBars.first == controller);
hideCurrentSnackBar();
},
null, // SnackBar doesn't use a builder function so setState() wouldn't rebuild it
);
try {
setState(() {
_snackBars.addLast(controller);
});
_updateScaffolds();
} catch (exception) {
assert (() {
if (exception is FlutterError) {
final String summary = exception.diagnostics.first.toDescription();
if (summary == 'setState() or markNeedsBuild() called during build.') {
final List<DiagnosticsNode> information = <DiagnosticsNode>[
ErrorSummary('The showSnackBar() method cannot be called during build.'),
ErrorDescription(
'The showSnackBar() method was called during build, which is '
'prohibited as showing snack bars requires updating state. Updating '
'state is not possible during build.',
),
ErrorHint(
'Instead of calling showSnackBar() during build, call it directly '
'in your on tap (and related) callbacks. If you need to immediately '
'show a snack bar, make the call in initState() or '
'didChangeDependencies() instead. Otherwise, you can also schedule a '
'post-frame callback using SchedulerBinding.addPostFrameCallback to '
'show the snack bar after the current frame.',
),
context.describeOwnershipChain(
'The ownership chain for the particular ScaffoldMessenger is',
),
];
throw FlutterError.fromParts(information);
}
}
return true;
}());
rethrow;
}
return controller;
}