Skip to main content
← back

app toast

lib/app_toast.dart · flutter · dart

a toast for flutter in one file. no packages, no DI, no widget wrapping. works with any architecture.

llms.txt

tldr

copy one file into your project, register a navigator key, call AppToast.success(message: "saved") from anywhere. no context needed.

spring entry, card stacking, swipe to dismiss in any direction, duplicate shake, and an optional expand then collapse width animation.

live demo

starting the demo

install

copy one file

grab it and drop it in at lib/app_toast.dart.

app_toast.dart1593 lines

that's the whole dependency list. it imports dart:async, dart:math and flutter sdk libraries (material, physics, scheduler). nothing goes into pubspec.yaml.

register a root navigator key

make the key, hand it to AppToast at startup.

final navigatorKey = GlobalKey<NavigatorState>();

void main() {
  AppToast.init(navigatorKey: navigatorKey);
  runApp(const MyApp());
}

attach it to your app

same instance goes on your router or app.

go_router

GoRouter(
  navigatorKey: navigatorKey,
  routes: [...],
);

plain MaterialApp

MaterialApp(
  navigatorKey: navigatorKey,
  home: const HomeView(),
);

init(navigatorKey: ...) is required. calling show() before init throws a StateError.

usage

call it from anywhere. a widget, a view model, a repository, an interceptor. no BuildContext needed.

AppToast.show(
  message: "Changes saved",
  description: "Your draft is safe",
  event: AppToastEvent.success,
  animated: true,
);

shortcuts for each variant.

AppToast.success(message: "Saved");
AppToast.error(message: "Could not save", description: "Check your connection");
AppToast.warning(message: "Two items need review");
AppToast.info(message: "Syncing…");

clear everything on screen.

AppToast.dismissAll();              // animated
AppToast.dismissAll(animated: false); // immediate

example

class HomeView extends StatelessWidget {
  const HomeView({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () => AppToast.success(
            message: "Changes saved",
            description: "Your draft is safe",
            animated: true,
          ),
          child: const Text("Save"),
        ),
      ),
    );
  }
}

reference

everything below is here when you need it. you can ship without reading any of it.