cherry_toast_msgs 1.3.0
cherry_toast_msgs: ^1.3.0 copied to clipboard
A beautiful, responsive toast notification package for Flutter with animated overlays, customizable themes, builder pattern API, queue management, and advanced interactive features.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:cherry_toast_msgs/cherry_toast_msgs.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Cherry Toast Messages Example',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _toastCount = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Cherry Toast Messages v1.3.0'),
actions: [
IconButton(
icon: const Icon(Icons.clear_all),
onPressed: () {
CherryToastMsgs.clearQueue();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Toast queue cleared!'),
backgroundColor: Colors.red,
),
);
},
tooltip: 'Clear Queue',
),
],
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Header
const Text(
'Cherry Toast Messages Demo',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
Text(
'Comprehensive test of all features and widgets',
style: TextStyle(fontSize: 16, color: Colors.grey.shade600),
textAlign: TextAlign.center,
),
const SizedBox(height: 20),
// Queue Status Card
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Queue Status',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
color: Colors.blue.shade100,
borderRadius: BorderRadius.circular(20),
),
child: Text(
'Queue: ${CherryToastMsgs.queueSize}',
style: TextStyle(
color: Colors.blue.shade700,
fontWeight: FontWeight.bold,
),
),
),
],
),
const SizedBox(height: 8),
Text(
'Total toasts created: $_toastCount',
style: TextStyle(color: Colors.grey.shade600),
),
],
),
),
),
const SizedBox(height: 20),
// Basic Toast Types Section
_buildSectionHeader('Basic Toast Types'),
const SizedBox(height: 12),
// Success Toast Button
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.showSuccessToast(
context: context,
title: "Success!",
description: "Your action was completed successfully.",
);
},
icon: const Icon(Icons.check_circle, color: Colors.green),
label: const Text('Show Success Toast'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green.shade50,
foregroundColor: Colors.green.shade700,
),
),
const SizedBox(height: 8),
// Error Toast Button
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.showErrorToast(
context,
"Error!",
"Something went wrong. Please try again.",
);
},
icon: const Icon(Icons.error, color: Colors.red),
label: const Text('Show Error Toast'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red.shade50,
foregroundColor: Colors.red.shade700,
),
),
const SizedBox(height: 8),
// Warning Toast Button
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.showWarningToast(
context,
"Warning!",
"Please check your input before proceeding.",
);
},
icon: const Icon(Icons.warning, color: Colors.orange),
label: const Text('Show Warning Toast'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange.shade50,
foregroundColor: Colors.orange.shade700,
),
),
const SizedBox(height: 8),
// Info Toast Button
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.showInfoToast(
context,
"Information",
"Here's some useful information for you.",
);
},
icon: const Icon(Icons.info, color: Colors.blue),
label: const Text('Show Info Toast'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue.shade50,
foregroundColor: Colors.blue.shade700,
),
),
const SizedBox(height: 20),
// Builder Pattern Section
_buildSectionHeader('🏗️ Builder Pattern API (New!)'),
const SizedBox(height: 12),
// Simple Builder Example
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Builder Pattern")
.description(
"This toast was created using the fluent builder API",
)
.success()
.show();
},
icon: const Icon(Icons.build, color: Colors.green),
label: const Text('Simple Builder Toast'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green.shade50,
foregroundColor: Colors.green.shade700,
),
),
const SizedBox(height: 8),
// Advanced Builder Example
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Advanced Builder")
.description("With haptic feedback and custom duration")
.error()
.hapticFeedback()
.duration(const Duration(seconds: 4))
.callbacks(
ToastCallbacks(
onShow: () => print('Advanced toast shown!'),
onDismiss: () => print('Advanced toast dismissed!'),
),
)
.show();
},
icon: const Icon(Icons.settings, color: Colors.red),
label: const Text('Advanced Builder Toast'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red.shade50,
foregroundColor: Colors.red.shade700,
),
),
const SizedBox(height: 20),
// Theme System Section
_buildSectionHeader('🎨 Theme System (New!)'),
const SizedBox(height: 12),
// Light Theme Toast
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Light Theme")
.description("Using predefined light theme")
.theme(CherryToastTheme.info)
.show();
},
icon: const Icon(Icons.light_mode, color: Colors.blue),
label: const Text('Light Theme Toast'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue.shade50,
foregroundColor: Colors.blue.shade700,
),
),
const SizedBox(height: 8),
// Dark Theme Toast
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Dark Theme")
.description("Using dark theme variant")
.warning()
.darkMode()
.show();
},
icon: const Icon(Icons.dark_mode, color: Colors.grey),
label: const Text('Dark Theme Toast'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey.shade50,
foregroundColor: Colors.grey.shade700,
),
),
const SizedBox(height: 8),
// Custom Theme Toast
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
final customTheme = CherryToastTheme.success.copyWith(
backgroundColor: Colors.purple.shade50,
borderColor: Colors.purple.shade200,
iconBackground: Colors.purple,
);
CherryToastMsgs.builder()
.context(context)
.title("Custom Theme")
.description("Using custom theme colors")
.theme(customTheme)
.show();
},
icon: const Icon(Icons.palette, color: Colors.purple),
label: const Text('Custom Theme Toast'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.purple.shade50,
foregroundColor: Colors.purple.shade700,
),
),
const SizedBox(height: 20),
// Animation System Section
_buildSectionHeader('🎪 Animation System (New!)'),
const SizedBox(height: 12),
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Slide Animation")
.description("Slides in from edge")
.info()
.animation(CherryToastAnimation.slide)
.show();
},
child: const Text('Slide'),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Fade Animation")
.description("Fades in smoothly")
.success()
.animation(CherryToastAnimation.fade)
.show();
},
child: const Text('Fade'),
),
),
],
),
const SizedBox(height: 8),
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Scale Animation")
.description("Scales from center")
.warning()
.animation(CherryToastAnimation.scale)
.show();
},
child: const Text('Scale'),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Bounce Animation")
.description("Bounces with elastic effect")
.error()
.animation(CherryToastAnimation.bounce)
.show();
},
child: const Text('Bounce'),
),
),
],
),
const SizedBox(height: 20),
// Interactive Features Section
_buildSectionHeader('👆 Interactive Features (New!)'),
const SizedBox(height: 12),
// Toast with Action Buttons
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.width(300)
.height(150)
.context(context)
.title("Interactive Toast")
.description("Toast with action buttons")
.warning()
.actions([
TextButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Retry pressed!')),
);
},
child: const Text('Retry'),
),
TextButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Cancel pressed!')),
);
},
child: const Text('Cancel'),
),
])
.show();
},
icon: const Icon(Icons.touch_app, color: Colors.orange),
label: const Text('Toast with Actions'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange.shade50,
foregroundColor: Colors.orange.shade700,
),
),
const SizedBox(height: 8),
// Toast with Callbacks
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Callback Toast")
.description("With lifecycle callbacks")
.info()
.callbacks(
ToastCallbacks(
onShow: () => print('Toast shown!'),
onDismiss: () => print('Toast dismissed!'),
onTap: () {
print('Toast tapped!');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Toast was tapped!')),
);
},
onDismissed: (reason) =>
print('Toast dismissed: $reason'),
),
)
.show();
},
icon: const Icon(Icons.functions, color: Colors.blue),
label: const Text('Toast with Callbacks'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue.shade50,
foregroundColor: Colors.blue.shade700,
),
),
const SizedBox(height: 8),
// Haptic Feedback Toast
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Haptic Feedback")
.description("Feel the vibration!")
.success()
.hapticFeedback()
.show();
},
icon: const Icon(Icons.vibration, color: Colors.green),
label: const Text('Haptic Feedback Toast'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green.shade50,
foregroundColor: Colors.green.shade700,
),
),
const SizedBox(height: 20),
// Configuration System Section
_buildSectionHeader('⚙️ Configuration System (New!)'),
const SizedBox(height: 12),
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Quick Toast")
.description("2 seconds, fast animation")
.success()
.quick()
.show();
},
child: const Text('Quick Config'),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Persistent Toast")
.description("8 seconds, always closeable")
.warning()
.persistent()
.show();
},
child: const Text('Persistent Config'),
),
),
],
),
const SizedBox(height: 20),
// Positioning Section
_buildSectionHeader('📍 Positioning'),
const SizedBox(height: 12),
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Top Toast")
.description("Positioned at top")
.info()
.top()
.show();
},
child: const Text('Top'),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Center Toast")
.description("Positioned at center")
.success()
.center()
.show();
},
child: const Text('Center'),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.builder()
.context(context)
.title("Bottom Toast")
.description("Positioned at bottom")
.error()
.bottom()
.show();
},
child: const Text('Bottom'),
),
),
],
),
const SizedBox(height: 20),
// Queue Management Section
_buildSectionHeader('🔄 Queue Management (New!)'),
const SizedBox(height: 12),
// Multiple Toasts Button
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount += 5);
for (int i = 0; i < 5; i++) {
CherryToastMsgs.builder()
.context(context)
.title("Queued Toast ${i + 1}")
.description("This toast is automatically queued")
.info()
.show();
}
},
icon: const Icon(Icons.queue, color: Colors.blue),
label: const Text('Create 5 Queued Toasts'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue.shade50,
foregroundColor: Colors.blue.shade700,
),
),
const SizedBox(height: 8),
// Clear Queue Button
ElevatedButton.icon(
onPressed: () {
CherryToastMsgs.clearQueue();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Toast queue cleared!'),
backgroundColor: Colors.red,
),
);
setState(() {}); // Refresh queue status
},
icon: const Icon(Icons.clear_all, color: Colors.red),
label: const Text('Clear Toast Queue'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red.shade50,
foregroundColor: Colors.red.shade700,
),
),
const SizedBox(height: 20),
// Static Info Containers Section
_buildSectionHeader('🏷️ Static Info Containers'),
const SizedBox(height: 12),
// Default Static Info Container
const StaticInfoContainer(
message:
"This is a default static information container with blue theme",
),
const SizedBox(height: 12),
// Success Static Info Container
StaticInfoContainer(
message: "This is a success static container with green theme",
icon: Icons.check_circle,
backgroundColor: Colors.green.shade50,
borderColor: Colors.green.shade200,
iconColor: Colors.green.shade600,
textColor: Colors.green.shade700,
),
const SizedBox(height: 12),
// Warning Static Info Container
StaticInfoContainer(
message: "This is a warning static container with orange theme",
icon: Icons.warning,
backgroundColor: Colors.orange.shade50,
borderColor: Colors.orange.shade200,
iconColor: Colors.orange.shade600,
textColor: Colors.orange.shade700,
),
const SizedBox(height: 12),
// Error Static Info Container
StaticInfoContainer(
message: "This is an error static container with red theme",
icon: Icons.error,
backgroundColor: Colors.red.shade50,
borderColor: Colors.red.shade200,
iconColor: Colors.red.shade600,
textColor: Colors.red.shade700,
),
const SizedBox(height: 12),
// Custom Size Static Info Container
StaticInfoContainer(
message:
"This is a custom sized static container with fixed dimensions",
icon: Icons.aspect_ratio,
backgroundColor: Colors.purple.shade50,
borderColor: Colors.purple.shade200,
iconColor: Colors.purple.shade600,
textColor: Colors.purple.shade700,
width: 350,
height: 80,
),
const SizedBox(height: 20),
// Custom Toast Section
_buildSectionHeader('🎨 Custom Styling'),
const SizedBox(height: 12),
ElevatedButton.icon(
onPressed: () {
setState(() => _toastCount++);
CherryToastMsgs.showAnimatedToast(
context: context,
title: "Custom Styled Toast",
description: "Fully customized appearance with purple theme",
icon: Icons.star,
iconColor: Colors.white,
iconBackground: Colors.purple,
backgroundColor: Colors.purple.shade50,
borderColor: Colors.purple.shade200,
titleStyle: const TextStyle(
color: Colors.purple,
fontWeight: FontWeight.bold,
fontSize: 18,
),
descriptionStyle: TextStyle(
color: Colors.purple.shade600,
fontSize: 16,
),
borderRadius: 16,
borderWidth: 2,
duration: const Duration(seconds: 5),
elevation: 12,
width: 320,
height: 140,
animationType: CherryToastAnimation.bounce,
);
},
icon: const Icon(Icons.star, color: Colors.purple),
label: const Text('Custom Styled Toast'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.purple.shade50,
foregroundColor: Colors.purple.shade700,
),
),
const SizedBox(height: 30),
// Device Info Display
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Device Information:',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
Builder(
builder: (context) {
final size = MediaQuery.of(context).size;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildInfoRow(
'Screen Width',
'${size.width.toStringAsFixed(0)}px',
),
_buildInfoRow(
'Screen Height',
'${size.height.toStringAsFixed(0)}px',
),
_buildInfoRow(
'Device Type',
size.width > 600 ? 'Tablet/Desktop' : 'Mobile',
),
_buildInfoRow(
'Orientation',
size.width > size.height
? 'Landscape'
: 'Portrait',
),
_buildInfoRow(
'Pixel Ratio',
MediaQuery.of(
context,
).devicePixelRatio.toStringAsFixed(2),
),
],
);
},
),
],
),
),
),
const SizedBox(height: 20),
// Footer
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
const Text(
'🎉 Cherry Toast Messages v1.3.0',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Text(
'All features and widgets have been tested successfully!',
style: TextStyle(color: Colors.grey.shade600),
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
Text(
'Created by Abdullah Ahmed',
style: TextStyle(color: Colors.grey.shade500, fontSize: 12),
textAlign: TextAlign.center,
),
],
),
),
],
),
),
);
}
Widget _buildSectionHeader(String title) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
decoration: BoxDecoration(
color: Colors.blue.shade50,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.blue.shade200),
),
child: Text(
title,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.blue.shade700,
),
),
);
}
Widget _buildInfoRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('$label:', style: const TextStyle(fontWeight: FontWeight.w500)),
Text(value, style: TextStyle(color: Colors.grey.shade600)),
],
),
);
}
}