toast_lift 1.0.2
toast_lift: ^1.0.2 copied to clipboard
Beautiful animated toast notifications for Flutter apps with modern UI and smooth animations.
import 'package:flutter/material.dart';
import 'package:toast_lift/toast_lift.dart';
import 'toast_preview_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Color _softBg(Color color) => color.withValues(alpha: 0.10);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Builder(
builder: (context) {
return Scaffold(
backgroundColor: const Color(0xffeef2f7),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(22),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 28),
Container(
padding: const EdgeInsets.all(22),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xff111827), Color(0xff1f2937)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(32),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.18),
blurRadius: 30,
offset: const Offset(0, 14),
),
],
),
child: const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"ToastLift",
style: TextStyle(
color: Colors.white,
fontSize: 36,
fontWeight: FontWeight.w800,
),
),
SizedBox(height: 10),
Text(
"Modern animated toast messages for beautiful Flutter apps.",
style: TextStyle(
color: Colors.white70,
fontSize: 15,
height: 1.5,
),
),
],
),
),
const SizedBox(height: 28),
const Text(
"Choose Toast Type",
style: TextStyle(
color: Colors.black87,
fontSize: 18,
fontWeight: FontWeight.w800,
),
),
const SizedBox(height: 16),
_demoButton(
context,
title: "Success Toast",
icon: Icons.check_circle,
color: Colors.green,
type: ToastLiftType.success,
message: "Profile saved successfully!",
),
_demoButton(
context,
title: "Error Toast",
icon: Icons.error,
color: Colors.red,
type: ToastLiftType.error,
message: "Something went wrong!",
),
_demoButton(
context,
title: "Warning Toast",
icon: Icons.warning,
color: Colors.orange,
type: ToastLiftType.warning,
message: "Please check your input.",
),
_demoButton(
context,
title: "Info Toast",
icon: Icons.info,
color: Colors.blue,
type: ToastLiftType.info,
message: "New update is available.",
),
_demoButton(
context,
title: "Loading Toast",
icon: Icons.hourglass_bottom,
color: Colors.purple,
type: ToastLiftType.loading,
message: "Uploading your file...",
),
],
),
),
),
);
},
),
);
}
Widget _demoButton(
BuildContext context, {
required String title,
required IconData icon,
required Color color,
required ToastLiftType type,
required String message,
}) {
return ToastDemoCard(
title: title,
icon: icon,
color: color,
onTap: () {
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: const Duration(milliseconds: 450),
pageBuilder: (_, animation, __) => ToastPreviewPage(
title: title,
description: type == ToastLiftType.success
? "Your profile has been updated successfully."
: type == ToastLiftType.error
? "Payment failed due to a network issue. Please try again."
: type == ToastLiftType.warning
? "Deleting this file cannot be undone."
: type == ToastLiftType.info
? "A new update is available for your application."
: "Uploading your files to the cloud storage...",
icon: icon,
color: color,
type: type,
message: message,
animationPath: type == ToastLiftType.success
? "assets/animations/Success.json"
: type == ToastLiftType.error
? "assets/animations/error.json"
: type == ToastLiftType.warning
? "assets/animations/Alert.json"
: type == ToastLiftType.info
? "assets/animations/info.json"
: "assets/animations/loading_anim.json",
),
transitionsBuilder: (_, animation, __, child) {
final curved = CurvedAnimation(
parent: animation,
curve: Curves.easeOutCubic,
);
return FadeTransition(
opacity: curved,
child: SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, 0.08),
end: Offset.zero,
).animate(curved),
child: child,
),
);
},
),
);
},
);
}
}
class ToastDemoCard extends StatefulWidget {
final String title;
final IconData icon;
final Color color;
final VoidCallback onTap;
const ToastDemoCard({
super.key,
required this.title,
required this.icon,
required this.color,
required this.onTap,
});
@override
State<ToastDemoCard> createState() => _ToastDemoCardState();
}
class _ToastDemoCardState extends State<ToastDemoCard> {
bool _isPressed = false;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(bottom: 14),
child: GestureDetector(
onTapDown: (_) => setState(() => _isPressed = true),
onTapCancel: () => setState(() => _isPressed = false),
onTapUp: (_) {
setState(() => _isPressed = false);
widget.onTap();
},
child: AnimatedScale(
scale: _isPressed ? 0.96 : 1,
duration: const Duration(milliseconds: 140),
curve: Curves.easeOut,
child: AnimatedContainer(
duration: const Duration(milliseconds: 220),
curve: Curves.easeOut,
height: 68,
padding: const EdgeInsets.symmetric(horizontal: 18),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(24),
boxShadow: [
BoxShadow(
color: widget.color.withValues(alpha: _isPressed ? 0.22 : 0.14),
blurRadius: _isPressed ? 14 : 24,
offset: Offset(0, _isPressed ? 6 : 12),
),
],
),
child: Row(
children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: widget.color.withValues(alpha: 0.10),
borderRadius: BorderRadius.circular(16),
),
child: Icon(widget.icon, color: widget.color, size: 25),
),
const SizedBox(width: 15),
Text(
widget.title,
style: const TextStyle(
color: Colors.black,
fontSize: 17,
fontWeight: FontWeight.w800,
),
),
const Spacer(),
Icon(Icons.arrow_forward_ios, color: widget.color, size: 16),
],
),
),
),
),
);
}
}