How to make Custom Toast Messages in flutter

Mayank Khandelwal
4 min readJul 28, 2019

--

Toasts are the information, messages, tool-tip or warning that are displayed on the screen similar to a pop up notification and are visible for only a short duration of time. They hover over the whole UI and are not bound to scroll or to any element on the screen.

Now unlike Android, we don’t have a ‘Toast’ class in flutter that we can make use of. We can use flutter packages like ‘fluttertoast’ and ‘toast’ which do offer some customization but I’ll show you how you can totally play around with your toast messages and even add images to them along with animations and possible gesture behaviors to them without using these packages.

So, we’ll be making something like this.

Without wasting any more time, let’s just dive straight into the code.
Make a new file and name it ‘toast_utils.dart’. Here’s what it will look like:

import 'dart:async';

import 'package:custom_toast/toast_animation.dart';
import 'package:flutter/material.dart';

class ToastUtils {
static Timer toastTimer;
static OverlayEntry _overlayEntry;

static void showCustomToast(BuildContext context,
String message) {

if (toastTimer == null || !toastTimer.isActive) {
_overlayEntry = createOverlayEntry(context, message);
Overlay.of(context).insert(_overlayEntry);
toastTimer = Timer(Duration(seconds: 2), () {
if (_overlayEntry != null) {
_overlayEntry.remove();
}
});
}

}

static OverlayEntry createOverlayEntry(BuildContext context,
String message) {

return OverlayEntry(
builder: (context) => Positioned(
top: 50.0,
width: MediaQuery.of(context).size.width - 20,
left: 10,
child: ToastMessageAnimation(Material(
elevation: 10.0,
borderRadius: BorderRadius.circular(10),
child: Container(
padding:
EdgeInsets.only(left: 10, right: 10,
top: 13, bottom: 10),
decoration: BoxDecoration(
color: Color(0xffe53e3f),
borderRadius: BorderRadius.circular(10)),
child: Align(
alignment: Alignment.center,
child: Text(
message,
textAlign: TextAlign.center,
softWrap: true,
style: TextStyle(
fontSize: 18,
color: Color(0xFFFFFFFF),
),
),
),
),
)),
));
}
}

Let’s break down the above code.
The secret ingredient here is the OverlayEntry class. Look into the docs and you’ll see that it works on Stack widget. But differs in the way that it is not bound to any widget/element of the UI. However, there are ways to bind its position to some element of the UI. You can read more about OverlayEntry class here.

OverlayEntry constructor gives us ‘builder’, ‘opaque’ and ‘maintainState’ parameters, all of which are self explanatory.
Now since OverLayEntry class use stack, we can use Positioned widget inside builder parameter. Inside Positioned, you can see use width, height, top, right, bottom, left parameters to set the position of the toast accordingly. An important thing to remember here is this :

For Positioned, only two out of the three horizontal values (left, right, width), and only two out of the three vertical values (top, bottom, height), can be set. In each case, at least one of the three must be null.

Then, inside the child you can design your widget as you wish. Use images or texts or anything. Don’t get confused with ToastMessageAnimation, we’ll get to that later.
Now in the showCustomToast method, the following line shows the overlay on the screen:

Overlay.of(context).insert(_overlayEntry);

And the following line, removes it from the screen:

_overlayEntry.remove();

I’ve used Timer class to show the toast for duration of 2 seconds and then remove it.
Simple. And looks nice. Now it’s time for some animation. As you would’ve seen in the video, the toast coming from the top with fadeIn animation and then goes back to top with fadeOut animation.

To achieve that, I’ve used a flutter package called simple_animations developed by Felix Blaschke. It’s very easy to use and you can do plenty of stuff with it from very basic animations to combining loads of animations without much overhead.
Add the package name in your pubspec.yaml file under dependencies:

simple_animations: ^1.3.3

Now, make a new dart file under lib folder, name it toast_animation. Here is what it will look like:

import 'package:flutter/material.dart';
import 'package:simple_animations/simple_animations.dart';

class ToastMessageAnimation extends StatelessWidget {
final Widget child;

ToastMessageAnimation(this.child);

@override
Widget build(BuildContext context) {
final tween = MultiTrackTween([
Track("translateY")
.add(
Duration(milliseconds: 250),
Tween(begin: -100.0, end: 0.0),
curve: Curves.easeOut,
)
.add(Duration(seconds: 1, milliseconds: 250),
Tween(begin: 0.0, end: 0.0))
.add(Duration(milliseconds: 250),
Tween(begin: 0.0, end: -100.0),
curve: Curves.easeIn),
Track("opacity")
.add(Duration(milliseconds: 500),
Tween(begin: 0.0, end: 1.0))
.add(Duration(seconds: 1),
Tween(begin: 1.0, end: 1.0))
.add(Duration(milliseconds: 500),
Tween(begin: 1.0, end: 0.0)),
]);

return ControlledAnimation(
duration: tween.duration,
tween: tween,
child: child,
builderWithChild: (context, child, animation) => Opacity(
opacity: animation["opacity"],
child: Transform.translate(
offset: Offset(0, animation["translateY"]),
child: child),
),
);
}
}

Don’t be overwhelmed if you don’t understand it. Let’s walk through it.
In the constructor, we take the widget as parameter on which we want to apply the animation.
Tween is a flutter class that provides linear interpolation between a starting and ending point. We use this class in animations to provide the range of our animation.
MultiTrackTween is used to combine different animations into one. You’ll notice that we are using ‘translateY’ and ‘opacity’ properties. In each of these, we have added animation for three different duration — first is incoming animation for toast, second is while toast stays on the screen and third when the toast is going off the screen.
Next we return the ControlledAnimation widget with duration, child, tween and builderWithChild parameters. See how we use the same keywords (opacity and translateY) to apply the animations that we specified in the MultiTrackTween.

And that’s it. Call showCustomToast method to show your custom toast anywhere in the app. For demonstration, I am calling that method on the tap of the FloatingActionButton in home page.

floatingActionButton: FloatingActionButton(
onPressed: (){
ToastUtils.showCustomToast(context, "This is a toast message");
},
child: Icon(Icons.add),
),

With minor tweaks, you can also add images into your toast messages like this:

Link to Github repository -> https://github.com/Mayankk1995/custom_toast_flutter

Thank you for reading. If you found this article informative, press the clap icon as many times you wish. Cheers!

--

--

Mayank Khandelwal
Mayank Khandelwal

Written by Mayank Khandelwal

Trying to go big because playing small never serves the world. Know more about me - https://tinteduniverse.com/

Responses (2)