showSnackBar method

ScaffoldFeatureController<SnackBar, SnackBarClosedReason> showSnackBar(
  1. SnackBar snackBar, {
  2. AnimationStyle? snackBarAnimationStyle,
})

Shows a SnackBar across all registered Scaffolds. Scaffolds register to receive snack bars from their closest ScaffoldMessenger ancestor. If there are several registered scaffolds the snack bar is shown simultaneously on all of them.

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.
link

To create a local project with this code sample, run:
flutter create --sample=material.ScaffoldMessengerState.showSnackBar.1 mysample

Relative positioning of floating SnackBars

A SnackBar with SnackBar.behavior set to SnackBarBehavior.floating is positioned above the widgets provided to Scaffold.floatingActionButton, Scaffold.persistentFooterButtons, and Scaffold.bottomNavigationBar. If some or all of these widgets take up enough space such that the SnackBar would not be visible when positioned above them, an error will be thrown. In this case, consider constraining the size of these widgets to allow room for the SnackBar to be visible.

Here is an example showing how to display a SnackBar with showSnackBar
link

To create a local project with this code sample, run:
flutter create --sample=material.ScaffoldMessengerState.showSnackBar.2 mysample

Here is an example showing that a floating SnackBar appears above Scaffold.floatingActionButton.
link

To create a local project with this code sample, run:
flutter create --sample=material.ScaffoldMessengerState.showSnackBar.3 mysample

If AnimationStyle.duration is provided in the snackBarAnimationStyle parameter, it will be used to override the snackbar show animation duration. Otherwise, defaults to 250ms.

If AnimationStyle.reverseDuration is provided in the snackBarAnimationStyle parameter, it will be used to override the snackbar hide animation duration. Otherwise, defaults to 250ms.

To disable the snackbar animation, use AnimationStyle.noAnimation.

This sample showcases how to override SnackBar show and hide animation duration using AnimationStyle in ScaffoldMessengerState.showSnackBar.
link

To create a local project with this code sample, run:
flutter create --sample=material.ScaffoldMessengerState.showSnackBar.4 mysample

Implementation

ScaffoldFeatureController<SnackBar, SnackBarClosedReason> showSnackBar(
  SnackBar snackBar,
  { AnimationStyle? snackBarAnimationStyle }
) {
  assert(
    _scaffolds.isNotEmpty,
    'ScaffoldMessenger.showSnackBar was called, but there are currently no '
    'descendant Scaffolds to present to.',
  );
  _didUpdateAnimationStyle(snackBarAnimationStyle);
  _snackBarController ??= SnackBar.createAnimationController(
      duration: snackBarAnimationStyle?.duration,
      reverseDuration: snackBarAnimationStyle?.reverseDuration,
      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;
}