showSnackbar function

OverlayEntry showSnackbar(
  1. BuildContext context,
  2. Widget snackbar, {
  3. Duration? duration = snackbarShortDuration,
  4. Alignment alignment = Alignment.bottomCenter,
  5. EdgeInsetsGeometry margin = const EdgeInsets.all(16.0),
  6. VoidCallback? onDismiss,
})

Shows a snackbar on the given context.

There must be an Overlay above in provided context tree, otherwise an asserion error is thrown.

duration defaults to snackbarShortDuration. It's recommended to use snackbarLongDuration for a extended snackbar duration. If null, the snackbar will long forever, and have to be dismissed manually.

alignment is used to align the snackbar within the screen. Defaults to Alignment.bottomCenter

margin is the margin applied to snackbar. Defaults to 16 logical pixels on all sides

onDismiss is called when the snackbar is dismissed after duration. It's not called if dismissed manually.

To dismiss the snackbar manually, use the following code:

final result = showSnackbar(context, snackbar);
result.remove();

Implementation

OverlayEntry showSnackbar(
  BuildContext context,
  Widget snackbar, {
  Duration? duration = snackbarShortDuration,
  Alignment alignment = Alignment.bottomCenter,
  EdgeInsetsGeometry margin = const EdgeInsets.all(16.0),
  VoidCallback? onDismiss,
}) {
  assert(debugCheckHasOverlay(context));
  final GlobalKey<SnackbarState> key = snackbar.key is GlobalKey<SnackbarState>
      ? snackbar.key as GlobalKey<SnackbarState>
      : GlobalKey<SnackbarState>();
  final entry = OverlayEntry(builder: (context) {
    if (snackbar is Snackbar) {
      return Padding(
        padding: margin,
        child: Align(
          alignment: alignment,
          child: Snackbar(
            key: key,
            content: snackbar.content,
            action: snackbar.action,
            extended: snackbar.extended,
          ),
        ),
      );
    }
    return Padding(
      padding: margin,
      child: Align(
        alignment: alignment,
        child: snackbar,
      ),
    );
  });
  Overlay.of(context)!.insert(entry);
  if (duration != null)
    Future.delayed(duration).then((value) async {
      if (entry.mounted) {
        if (snackbar is Snackbar) await key.currentState?.controller.reverse();
      }
      if (entry.mounted) {
        entry.remove();
        onDismiss?.call();
      }
    });
  return entry;
}