Toastr Flutter
A highly customizable Flutter package for displaying beautiful toast notifications with smooth animations, multiple types, and flexible positioning. Zero setup — just install and use!
Features ✨
- react-hot-toast animations: Faithful recreation of enter/exit animations with spring curves
- Multiple notification types: Success, Error, Warning, Info, Loading, Blank
- Flexible positioning: Top/Bottom with Left/Center/Right alignment + Center (default:
bottomCenter) - Animated icons: Checkmark draws in, X lines appear sequentially, spinner rotates — all with staggered delays
- Promise API: Auto-transition loading → success/error based on
Futureresult - Highly customizable: Colors, icons, duration, progress bars, and more
ToastrOptions: Clean single-object API for all optional parameters — no parameter explosion- Custom text styles:
titleStyleandmessageStylelet devs plug in their app's font and sizes - Interactive: Tap to dismiss, swipe-to-dismiss, and close button
- Dark theme: Built-in dark theme support (
ToastrTheme.dark) - Custom content: Pass any
Widgetas toast content - Callbacks:
onTapandonDismisscallbacks for interactive toasts - Compact mode: Reduced-padding layout for dense UIs
- Circular progress: Circular countdown ring as an alternative to the linear bar
- Keyboard avoidance: Toast auto-slides above the soft keyboard
- Icon theme: Per-toast icon color overrides via
ToastrIconTheme - Well tested: 91 unit tests with comprehensive coverage
- Responsive: Adaptive design for mobile, tablet, and desktop
- Zero setup: No
BuildContext, noinit(), nonavigatorKey— just call and go! - Secure: Built-in XSS sanitization, rate limiting, and input validation
Installation
Add this to your package's pubspec.yaml file:
dependencies:
toastr_flutter: ^2.5.0
Then run:
flutter pub get
Quick Start 🚀
Basic Usage
Import the package and start showing toasts from anywhere — no BuildContext needed:
import 'package:toastr_flutter/toastr.dart';
// That's it! No setup, no initialization, no context.
Toastr.success('Operation completed!');
Toastr.error('Something went wrong!');
Toastr.warning('Please check your input');
Toastr.info('Here is some information');
// Loading toast (stays until dismissed)
final id = Toastr.loading('Saving...');
// ... later
Toastr.dismiss(id);
// Promise API — auto-transitions loading → success/error
await Toastr.promise(
myFuture,
loading: 'Saving...',
success: 'Saved!',
error: 'Failed to save',
);
// Short alias
Toastr.success('Done!');
Full Example
import 'package:flutter/material.dart';
import 'package:toastr_flutter/toastr.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Toastr Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () => Toastr.success('Saved successfully!'),
child: const Text('Success'),
),
ElevatedButton(
onPressed: () => Toastr.error('Failed to save!'),
child: const Text('Error'),
),
ElevatedButton(
onPressed: () => Toastr.warning('Check your input'),
child: const Text('Warning'),
),
ElevatedButton(
onPressed: () => Toastr.info('New update available'),
child: const Text('Info'),
),
],
),
),
);
}
}
All Available Methods
// Success notification (green)
Toastr.success('Operation completed successfully!');
// Error notification (red)
Toastr.error('Something went wrong!');
// Warning notification (orange)
Toastr.warning('Please check your input');
// Info notification (blue)
Toastr.info('Here is some useful information');
// Auto-detect type from message content
Toastr.show('Success! Operation completed'); // Auto-detects as success
// Loading toast — stays on screen until dismissed
final id = Toastr.loading('Processing...');
// Blank toast — no icon
Toastr.blank('Plain message');
// Promise API — loading → success/error automatically
await Toastr.promise<Data>(
fetchData(),
loading: 'Fetching...',
success: 'Data loaded!',
error: 'Failed to fetch',
);
// Dismiss a specific toast by ID
Toastr.dismiss(id);
// Dismiss all toasts
Toastr.dismiss();
// Short alias — same API, shorter name
Toastr.success('Saved!');
Toastr.loading('Working...');
await Toastr.promise(future, loading: '...', success: '...', error: '...');
// Custom configuration
Toastr.custom(ToastrConfig(...));
Advanced Usage 🔧
Custom Configuration
For complete control over appearance and behavior:
Toastr.custom(ToastrConfig(
type: ToastrType.success,
message: 'Custom styled notification',
title: 'Custom Title',
duration: Duration(seconds: 5),
position: ToastrPosition.topRight,
showMethod: ToastrShowMethod.fadeIn,
hideMethod: ToastrHideMethod.fadeOut,
showDuration: Duration(milliseconds: 300),
hideDuration: Duration(milliseconds: 1000),
showProgressBar: true,
showCloseButton: true,
preventDuplicates: true,
));
Method Parameters
All helper methods accept a title named parameter and an optional ToastrOptions object for everything else:
Toastr.success(
'Your message here', // Required: message text
title: 'Optional Title', // Optional: direct named param
options: ToastrOptions(
duration: Duration(seconds: 3),
position: ToastrPosition.topRight,
showMethod: ToastrShowMethod.fadeIn,
hideMethod: ToastrHideMethod.fadeOut,
showDuration: Duration(milliseconds: 300),
hideDuration: Duration(milliseconds: 1000),
showProgressBar: false,
showCloseButton: false,
preventDuplicates: false,
titleStyle: TextStyle(fontFamily: 'Poppins', fontWeight: FontWeight.w800),
messageStyle: TextStyle(fontFamily: 'Poppins', fontSize: 14),
),
);
Global Configuration
Change default settings for all toasts:
Toastr.configure(
position: ToastrPosition.bottomCenter,
duration: Duration(seconds: 3),
showProgressBar: true,
showCloseButton: true,
);
Positioning Options
Choose where your notifications appear:
ToastrPosition.topLeft // Top-left corner
ToastrPosition.topCenter // Top-center
ToastrPosition.topRight // Top-right corner
ToastrPosition.bottomLeft // Bottom-left corner
ToastrPosition.bottomCenter // Bottom-center (default)
ToastrPosition.bottomRight // Bottom-right corner
ToastrPosition.center // Center of screen
Animation Options
Customize how notifications appear and disappear:
// Show methods
ToastrShowMethod.fadeIn // Fade in (default)
ToastrShowMethod.slideDown // Slide from top
ToastrShowMethod.slideUp // Slide from bottom
ToastrShowMethod.slideLeft // Slide from right
ToastrShowMethod.slideRight // Slide from left
ToastrShowMethod.show // Instant
// Hide methods
ToastrHideMethod.fadeOut // Fade out (default)
ToastrHideMethod.slideUp // Slide to top
ToastrHideMethod.slideDown // Slide to bottom
ToastrHideMethod.slideLeft // Slide to left
ToastrHideMethod.slideRight // Slide to right
ToastrHideMethod.hide // Instant
Managing Notifications
// Clear all active notifications
Toastr.clearAll();
// Clear only the last notification
Toastr.clearLast();
API Reference 📚
Toastr Methods
| Method | Description |
|---|---|
success(message, {...}) |
Show green success notification |
error(message, {...}) |
Show red error notification |
warning(message, {...}) |
Show orange warning notification |
info(message, {...}) |
Show blue info notification |
loading(message, {...}) |
Show loading spinner (stays until dismissed) |
blank(message, {...}) |
Show plain text toast without icon |
promise(future, {...}) |
Auto-transition loading → success/error |
show(message, {type}) |
Auto-detect type from message content |
custom(config) |
Show with full custom config |
dismiss([id]) |
Dismiss specific toast or all toasts |
configure({...}) |
Set global defaults |
clearAll() |
Clear all active notifications |
clearLast() |
Clear only the last notification |
Tip: All methods also available via the
Toastralias:Toastr.success(...),Toastr.promise(...), etc.
ToastrConfig Properties
| Property | Type | Default | Description |
|---|---|---|---|
type |
ToastrType |
required | success, error, warning, info |
message |
String |
required | Main message text |
title |
String? |
null | Optional title text |
duration |
Duration |
5 seconds | How long to display |
position |
ToastrPosition |
bottomCenter | Where to position |
showMethod |
ToastrShowMethod |
fadeIn | Show animation type |
hideMethod |
ToastrHideMethod |
fadeOut | Hide animation type |
showDuration |
Duration |
300ms | Show animation duration |
hideDuration |
Duration |
1000ms | Hide animation duration |
showProgressBar |
bool |
false | Show progress bar |
showCloseButton |
bool |
false | Show close button |
dismissible |
bool |
true | Allow tap to dismiss |
preventDuplicates |
bool |
false | Prevent duplicate messages |
onTap |
VoidCallback? |
null | Callback when toast is tapped |
onDismiss |
VoidCallback? |
null | Callback when toast exits |
content |
Widget? |
null | Custom widget content |
maxWidth |
double |
350 | Maximum toast width |
margin |
EdgeInsets? |
null | Custom margin from edges |
accentColor |
Color? |
null | Custom accent color |
containerDecoration |
BoxDecoration? |
null | Full style override |
theme |
ToastrTheme |
light | Color theme (light/dark) |
reverseOrder |
bool |
false | Stack order for new toasts |
compact |
bool |
false | Reduced-padding compact layout |
borderRadius |
BorderRadius? |
null | Custom border radius (default: 12px) |
avoidKeyboard |
bool |
true | Slide above soft keyboard |
stackOverlap |
double? |
null | Vertical overlap between toasts |
showCircularProgress |
bool |
false | Circular countdown indicator |
gutter |
double |
8 | Spacing between stacked toasts |
iconTheme |
ToastrIconTheme? |
null | Custom icon primary/secondary colors |
titleStyle |
TextStyle? |
null | Custom text style for title |
messageStyle |
TextStyle? |
null | Custom text style for message |
Responsive Design 📱
The package automatically adapts to different screen sizes:
- Mobile (< 768px): Compact layout with touch-friendly targets
- Tablet (768px - 1024px): Medium sizing with appropriate margins
- Desktop (> 1024px): Full-featured with optimal positioning
Examples 💡
Quick Notifications
// Simple toast from a button
ElevatedButton(
onPressed: () => Toastr.success('Saved!'),
child: Text('Save'),
)
// Error with custom duration
Toastr.error(
'Failed to save!',
duration: Duration(seconds: 10),
showCloseButton: true,
)
// From a callback, async handler, service — anywhere!
Future<void> fetchData() async {
try {
await api.getData();
Toastr.success('Data loaded');
} catch (e) {
Toastr.error('Failed to load data');
}
}
Loading & Promise
// Show a loading toast, update it when done
final id = Toastr.loading('Uploading file...');
await uploadFile();
Toastr.dismiss(id);
Toastr.success('File uploaded!');
// Or use promise() for automatic transitions
final result = await Toastr.promise<User>(
authService.login(email, password),
loading: 'Signing in...',
success: 'Welcome back!',
error: 'Invalid credentials',
);
// Blank toast — just text, no icon
Toastr.blank('Copied to clipboard');
// Using the Toastr alias
final loadId = Toastr.loading('Syncing...');
await syncData();
Toastr.dismiss(loadId);
Dark Theme
// Single toast
Toastr.success('Saved!', theme: ToastrTheme.dark);
// Global default
Toastr.configure(theme: ToastrTheme.dark);
Callbacks
Toastr.success(
'File uploaded',
onTap: () => openFile(),
onDismiss: () => cleanupTempFiles(),
);
Custom Content Widget
Toastr.blank(
'',
content: Row(
mainAxisSize: MainAxisSize.min,
children: [
CircleAvatar(backgroundImage: NetworkImage(avatarUrl)),
SizedBox(width: 8),
Text('John liked your post'),
],
),
);
Custom Font / Text Style
// Apply your app's font family and sizing to every toast
Toastr.configure(
titleStyle: TextStyle(fontFamily: 'Poppins', fontWeight: FontWeight.w800),
messageStyle: TextStyle(fontFamily: 'Poppins', letterSpacing: 0.1),
);
// Or override per-toast
Toastr.success(
'Saved!',
title: 'Success',
options: ToastrOptions(
titleStyle: TextStyle(fontFamily: 'Inter', fontSize: 16),
messageStyle: TextStyle(fontFamily: 'Inter', color: Colors.green.shade700),
),
);
// Full config
Toastr.custom(ToastrConfig(
type: ToastrType.info,
message: 'Notification',
titleStyle: TextStyle(fontFamily: 'Roboto', fontWeight: FontWeight.w900),
messageStyle: TextStyle(fontFamily: 'Roboto', fontSize: 12),
));
Custom Styling
Toastr.info(
'Wide toast',
maxWidth: 500,
margin: EdgeInsets.only(top: 60),
accentColor: Colors.purple,
containerDecoration: BoxDecoration(
color: Colors.indigo.shade900,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.indigo.shade400),
),
);
Compact Mode
// Smaller, denser layout — great for sidebars or data-heavy UIs
Toastr.success('Row saved', compact: true);
// Global compact default
Toastr.configure(compact: true);
Circular Progress Indicator
// Show a circular countdown ring instead of a linear bar
Toastr.info('Auto-closing…', showCircularProgress: true, showProgressBar: false);
Custom Icon Theme
// Override icon circle and checkmark colors independently
Toastr.success(
'Custom icon colors',
iconTheme: ToastrIconTheme(primary: Colors.purple, secondary: Colors.white),
);
Custom Border Radius & Gutter
Toastr.info(
'Pill shape',
borderRadius: BorderRadius.circular(32),
gutter: 12, // spacing between stacked toasts
);
Advanced Notifications
Toastr.custom(ToastrConfig(
type: ToastrType.info,
title: 'Update Available',
message: 'A new version is available. Update now?',
duration: Duration(seconds: 10),
position: ToastrPosition.bottomCenter,
showProgressBar: true,
showCloseButton: true,
preventDuplicates: true,
showMethod: ToastrShowMethod.slideUp,
hideMethod: ToastrHideMethod.fadeOut,
));
Screenshots 📸
🖥️ Desktop Experience
Configuration Panel
Comprehensive customization options |
Toast Notifications
Beautiful notifications in action |
📱 Mobile Experience
Mobile Interface
Responsive mobile design |
Mobile Toasts
Perfect mobile adaptation |
🎨 Responsive Design: Automatically adapts to different screen sizes — from mobile phones to desktop computers with consistent behavior and beautiful animations.
Migration Guide 🔄
From v1.0.0+7 to v2.0.0
Breaking Change: BuildContext is no longer needed. Remove context from all calls.
Before:
Toastr.success(context, 'Message');
Toastr.error(context, 'Error');
Toastr.custom(context, config);
After:
Toastr.success('Message');
Toastr.error('Error');
Toastr.custom(config);
No init(), no navigatorKey, no builder — just call the methods directly.
License 📄
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Contributing 🤝
Contributions are welcome! Please feel free to submit a Pull Request.
Made with ❤️ by Ignacio Manchu