animated_toast_list

pub package CI

A minimal, dependency-free toast list for Flutter. You design the toast. The package stacks, animates and hides it.

  • Your design: there are no built-in styles. A toast is any widget you build, with any animation.
  • Any type: a toast can be a String, your own model class, or a sealed class with a subtype for each kind of toast.
  • Minimal: two extension methods on BuildContext, no dependencies besides Flutter.
  • Works on all platforms, and stays above the current screen while navigating.

Live demo

More toasts than the limit Close button, timeout and persist
The oldest toast is hidden when the limit is reached Toasts are hidden with the close button or after the timeout, except a persistent toast
Toasts stay while navigating position: Alignment.bottomCenter, reverse: true
A toast stays visible on the next screen Toasts at the bottom of the screen, the newest last

Installation

flutter pub add animated_toast_list

Requires Flutter 3.10 or newer (Dart 3).

Usage

Wrap your MaterialApp (or CupertinoApp, WidgetsApp) with ToastListOverlay and build your toast in itemBuilder. Use the animation for the entrance and exit transitions. The toasts are displayed in the Overlay of the root Navigator, above every screen, tab and dialog. For more details, see the example.

Widget build(BuildContext context) {
  return ToastListOverlay<MyToastModel>(
    itemBuilder: (context, item, index, animation) =>
        ToastItem(animation: animation, item: item),
    child: MaterialApp(
      theme: ThemeData(colorSchemeSeed: Colors.blue),
      home: const MainScreen(),
    ),
  );
}
Property Default value Description
child Required Widget The wrapped widget.
itemBuilder Required ToastListItemBuilder Builds the toast widget.
position Alignment.topCenter Where the toasts are displayed.
reverse false Displays the newest toast at the bottom instead of the top.
limit 5 The maximum number of toasts displayed at the same time. When the limit is reached, the oldest toast is hidden.
width 375 The maximum width of the toasts.
timeoutDuration 5 seconds How long a toast is displayed.
useSafeArea true Keeps the toasts out of the status bar, the notch and the home indicator. Set it to false to display them edge to edge.

Show a toast

Call context.showToast from any widget below the ToastListOverlay, even in initState. You can see more details in the example.

context.showToast(MyToastModel('Saved', ToastType.success));

// Displayed for 10 seconds instead of timeoutDuration.
context.showToast(
  MyToastModel('Check your connection', ToastType.warning),
  duration: const Duration(seconds: 10),
);

// Not hidden after a timeout. It is still hidden when the limit is reached.
context.showToast(
  MyToastModel('Update available', ToastType.info),
  persist: true,
);

To show a toast outside of a screen, for example from a service, use the context of the navigatorKey of your app:

navigatorKey.currentContext!.showToast(MyToastModel('Saved', ToastType.success));

Note: MyToastModel is an example model. Any type can be used as a toast.

Hide a toast

Call context.hideToast with the toast. It is animated out with your itemBuilder.

context.hideToast(item);

To animate it out with a different widget, pass a builder:

context.hideToast(
  item,
  (context, animation) => ToastItem(animation: animation, item: item),
);

showToast returns a ToastHandle, which hides exactly that toast, even if other displayed toasts are equal to it:

final toast = context.showToast(
  MyToastModel('Uploading…', ToastType.info),
  persist: true,
);
await upload();
toast.hide();

Different kinds of toasts

Toasts whose type is a subtype of the type argument of ToastListOverlay can be shown, so a sealed class works well:

sealed class AppToast {}

class SuccessToast extends AppToast {}

class ErrorToast extends AppToast {
  ErrorToast(this.message);

  final String message;
}

ToastListOverlay<AppToast>(
  itemBuilder: (context, toast, index, animation) => switch (toast) {
    SuccessToast() => MySuccessToast(animation: animation),
    ErrorToast(:final message) =>
      MyErrorToast(message: message, animation: animation),
  },
  child: const MaterialApp(home: HomeScreen()),
);

context.showToast(ErrorToast('Something went wrong'));

Accessibility

Since you build the toast, wrap it with Semantics(liveRegion: true, child: ...) so screen readers announce it when it appears, as in the example.

package:material_ui

The toasts are placed on a transparent Material of package:flutter/material.dart. If your app uses package:material_ui instead, wrap your toast in a Material of package:material_ui, so that its ink effects and default text style work.

Libraries

animated_toast_list
A generic, animated list of toasts that can be displayed above any widget.