showSnackBar method Null safety

ScaffoldFeatureController<SnackBar, SnackBarClosedReason> showSnackBar(
  1. 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

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