fl_toast 3.1.0 fl_toast: ^3.1.0 copied to clipboard
A simple yet powerful Toast Library for Flutter. Works in all the platforms
fl_toast
A simple yet powerful Toast Library for Flutter
Features #
✔️ Easy-to-use - Made for new and advanced developers
✔️ Animations - Supports any kind of animation
✔️ Made Fully in flutter - No need to use platform channels to show toasts
✔️ BuildContext
is not necessary
Usage #
context
in all show toast methods are required and can't be null
, otherwise an AssertionError
is thrown.
Basic usage #
import 'package:flutter_toast/flutter_toast.dart';
/// Shows a plaftform-styled toast with a text.
await showTextToast(
text: 'My Awesome Toast',
context: context,
);
Show the platform-styled toast #
You can use showPlatformToast
to show the toast that best fits the running platform. Shows an AndroidToast
in Android
and Fuchsia
. Shows a StyledToast
in the other platforms.
await showPlatformToast(
child: Text('My Platform Toast'),
context: context,
);
await showAndroidToast(
child: Text('My awesome Android Toast'),
context: context,
);
Multi-toasts #
You can use showMultiToast
to show multiple toasts at the same time.
await showMultiToast(
toasts: [
Toast(child: Text('Toast 1')),
Toast(child: Text('Toast 2')),
],
context: context,
);
You can use showSequencialToasts
to show one toast after another. The duration of the toasts can NOT be null
.
await showSequencialToasts(
toasts: [
Toast(child: Text('First toast'), duration: Duration(seconds: 2)),
Toast(child: Text('Second toast'), duration: Duration(seconds: 1)),
],
context: context,
);
Toast Provider #
Ofter some people say: "I'd like to display toasts without context". Well, you can with ToastProvider
. Just wrap your widgets in a ToastProvider
and call ToastProvider.context
in the context
parameter:
MaterialApp(
home: ToastProvider(child: Home()),
),
void displayToast() {
showStyledToast(
child: Text('Awesome styled toast'),
context: ToastProvider.context,
);
}
There must be an Overlay
widget above ToastProvider
. In the example above, the Overlay
created by MaterialApp
's Navigator
is used.
Animations #
You can highly customize the animation by setting animationBuilder
. The default animation is a FadeTransition
. The following snippet animate the toast with a scale transition.
await showStyledToast(
child: Text('Styled toast with custom scale animation'),
context: context,
animationBuilder: (context, animation, child) {
return ScaleTransition(
scale: animation,
child: child,
);
}
);
Flutter already has a set of pre-built transitions for you to use. They are:
FadeTransition
(default)ScaleTransition
SlideTransition
RotationTransition
SizeTransition
AlignTransition
You can combine multilpe transitions to build the best experience to the user:
await showPlatformToast(
child: Text('Platform toast with multiple custom animations'),
context: context,
animationBuilder: (context, animation, child) {
return ScaleTransition(
scale: animation,
child: RotationTransition(
turns: animation,
child: child,
),
);
}
);
You can even use the animations package. We're gonna be using FadeScaleTransition
import 'package:animations/animations.dart';
await showStyledToast(
child: Text('Styled toast using animations package'),
context: context,
animationBuilder: (context, animation, child) {
return FadeScaleTransition(
animation: animation,
child: child,
);
}
);
If none of the animations above have satisfied you, you can create your own implicit animations.
Cookbook #
Learn how to create beautiful toasts.
Snackbar #
The snippet below shows how to create a beautiful toast that act like a Snackbar
. It's useful when you don't have a parent Scaffold
avaiable to show a proper snackbar.
According to the Material Design Guidelines:
They (Snackbars) automatically disappear from the screen after a minimum of 4 (four) seconds, and a maximum of 10 (ten) seconds.
Snackbars can span the entire width of a UI. However, they should not appear in front of navigation or other important UI elements like floating action buttons.
showToast(
interactive: true,
padding: EdgeInsets.zero,
alignment: Alignment(0, 1),
/// The duration the toast will be on the screen
duration: Duration(seconds: 4),
/// The duration of the animation
animationDuration: Duration(milliseconds: 200),
/// Animate the toast to show up from the bottom
animationBuilder: (context, animation, child) {
return SlideTransition(
child: child,
position: Tween<Offset>(
begin: Offset(0, 1),
end: Offset(0, 0),
).animate(CurvedAnimation(
parent: animation,
curve: Curves.fastOutSlowIn,
)),
);
},
child: Dismissible(
key: ValueKey<String>('Snackbar'),
direction: DismissDirection.down,
child: Material(
elevation: Theme.of(context)?.snackBarTheme?.elevation ?? 6.0,
child: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14),
color: Color(0xFF323232),
child: Text('My Awesome Snackbar', style: TextStyle(color: Colors.white)),
),
),
),
context: context,
);
Drawer #
1. Create the ToastDrawer
Widget. #
It will be responsible by handling the dismiss color animation.
class ToastDrawer extends StatefulWidget {
const ToastDrawer({
Key key,
@required this.onCloseRequested,
@required this.content,
}) : super(key: key);
final Function onCloseRequested;
final Widget content;
@override
_ToastDrawerState createState() => _ToastDrawerState();
}
class _ToastDrawerState extends State<ToastDrawer> {
final key = GlobalKey<ToastState>();
final animDuration = Duration(milliseconds: 246);
Color backgroundColor = Colors.black54;
@override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned.fill(
child: GestureDetector(
onTap: () async {
setState(() => backgroundColor = Colors.transparent);
await key.currentState.dismissToastAnim();
widget.onCloseRequested();
},
child: AnimatedContainer(
duration: animDuration,
curve: Curves.ease,
color: backgroundColor,
),
),
),
Positioned.fill(
child: Toast(
key: key,
// Duration needs to be null, otherwise the toast will be in the screen
// but the reverse animation will be called.
duration: null,
alignment: Alignment.topLeft,
animationDuration: animDuration,
animationBuilder: (context, animation, child) {
return SlideTransition(
position: Tween<Offset>(
begin: Offset(-1, 0),
end: Offset(0, 0),
).animate(CurvedAnimation(
parent: animation,
curve: Curves.ease,
)),
child: child,
);
},
child: Dismissible(
key: ValueKey(1),
direction: DismissDirection.endToStart,
onDismissed: (_) => widget.onCloseRequested(),
child: Material(
elevation: 8,
child: Container(
width: MediaQuery.of(context).size.width * 0.75,
height: double.infinity,
// color: Colors.white,
child: widget.content,
),
),
),
),
),
],
);
}
}
2. Open the drawer #
Open the drawer using a persistent toast. A persistent toast is a toast that will only dismiss when asked so.
Note: Don't forget to set duration: null
in Toast
, otherwise the toast will leave the screen but won't be dismissed
void openDrawer(Widget content) async {
OverlayEntry entry;
entry = showPersistentToast(
context: context,
toast: ToastDrawer(
onCloseRequested: () => ToastManager.dismiss(entry),
content: content,
),
);
}
Advanced usage #
Dismiss a toast programatically #
To dismiss all the toasts in the screen, use ToastManager.dismissAll()
. To dismiss a toast programatically, you can just call ToastManager.dismiss(entry)
. The only way to get the entry
of a toast is to using showPersitentToast
.
To dismiss with animation, you'll need a GlobalKey
to access the toast state. The snippet below shows you how to do so:
final toastKey = GlobalKey<ToastState>();
final entry = showPersistentToast(
context: context,
toast: Toast(
key: toastKey,
duration: null,
),
);
Future.delayed(Duration(milliseconds: 250), () async {
await toastKey.currentState?.dismissToastAnim();
ToastManager.dismiss(entry);
});
Contribution #
Feel free to open an issue if you find an error or make pull requests.
Apps using this library #
Color Picker #
Color picker is an app to help developers pick the best color that best suits their designs. You can pick colors from:
- ✅ Wheel
- ✅ Palette
- ✅ Value
- ✅ Named
- ✅ Image
TODO: #
- Add screenshots to the readme
- Null-safety