How to Create a Toast Notification in Flutter™ Easily

Image for post
Image for post

Flutter toast notification messages are an essential part of an app. They are used to provide feedback to a user. Similar to a tooltip or a popup, they only remain on screen for a few seconds.

In this blog, we are going to share how to build such notification messages in 5 simple steps. More specifically, we are going to build reusable toast messages using alert dialogs, as shown in the image below:

Image for post
Image for post

Firstly, let us customize an alert dialog to appear as a toast message.

By using the showGeneralDialog method in Flutter, we can show an Alert Popup. Our objectives are to:

We will maintain all the code in a separate class. Hence, let us create a class with the name show_alert.dart.

Now let’s begin.

Step 1: Resize the Popup

To resize the popup, we set a height and width. Instead of setting a hard-coded value, we will take the device height and width using the MediaQuery.

Here is the code to obtain the height and width of the device:

Height: MediaQuery.of(context).size.heightWidth: MediaQuery.of(context).size.width

Below is the basic code of our Toast Message:

Note: Since this method is only used inside this class, we will create a private method.

void _showAlert(BuildContext context) {
showGeneralDialog(
context: context,
barrierDismissible: false,
barrierLabel:
MaterialLocalizations.of(context).modalBarrierDismissLabel,
transitionDuration: const Duration(milliseconds: 200),
pageBuilder: (BuildContext buildContext, Animation animation, Animation secondaryAnimation) {
return Material(
type: MaterialType.transparency,
child: WillPopScope(
onWillPop: () async => false,
child: Container(
width: MediaQuery.of(context).size.width — 40,
height: MediaQuery.of(context).size.height / 9,
padding: const EdgeInsets.all(5),
child: Container()),
),
);

We can deduce the toast height by dividing the device height by 9. The width can be deduced by subtracting 40 from the device width.

Step 2: Position popup at the bottom

To position the toast, we enclose the container inside an Align Widget.

By setting alignment as Alignment.bottomCenter, the toast message is now placed at the bottom.

For a better UX, we incorporate padding at the bottom as is shown in the code below:

Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
width: MediaQuery.of(context).size.width — 40,
height: MediaQuery.of(context).size.height / 9,
padding: const EdgeInsets.all(5),
child: Container()),
),
),

Step 3: Set a color & make it auto dismissible

In order to set a color and dismiss the popup, we pass a new parameter to the showAlert method as shown below:

void _showAlert(BuildContext context,Color color,bool shouldDismiss){..}

It is must be noted that we do not really require the ‘shouldDismiss’ parameter, but we include it for better reusability.

With the help of the decoration property, we set the color of our container. We can also set the shape and border radius of the toast inside this.

decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: const BorderRadius.vertical(top: Radius.circular(10), bottom: Radius.circular(10)),
color: color),

To set the auto dismiss feature, add the below code inside the pagebuilder:

if(shouldDismiss){
Future.delayed(const Duration(seconds: 4), () {
Navigator.of(context, rootNavigator: true).pop(‘true’);
});
}

We have set the duration here as 4 seconds. However, depending upon the requirement, you may change it accordingly or even pass it as a parameter.

Step 4: Build the message widget & its corresponding icon

To set the message and icon, we add three additional parameters:

The showAlert method now becomes

void _showAlert(BuildContext context,String message, Color color, IconData icon, Color iconColor,bool shouldDismiss) {..}

The message widget will be a row, which contains the icon, a SizedBox() and the Text widget as shown below:

Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(
icon,
size: 30,
color: iconColor,
),
const SizedBox(
width: 5,
),
Flexible(
child: Text(
message,
style: TextStyle(decoration: TextDecoration.none,color: Colors.black),
),
)
],
)

To deal with long messages, we wrapped the text widget inside the flexible widget.

Replace this code with a blank container(), that is included as a child in our Toast container.

Step 5: Configure scenario-based methods

Now that takes us to the final step. We will reuse this method based on scenarios. In this blog, we will cover the following three scenarios:

All that is needed is to simply call the showAlert method by passing the corresponding parameters.

Here are the Success, Info and Error methods-

void showSuccess(BuildContext context, String message,{bool shouldDismiss=true}) {
Timer.run(() => _showAlert(context,message, Color(0xFFE2F8FF), CupertinoIcons.check_mark_circled_solid, Color.fromRGBO(91, 180, 107, 1), shouldDismiss));
}

void showInfo(BuildContext context, String message,{bool shouldDismiss=true}) {
Timer.run(() => _showAlert(context,message, Color(0xFFE7EDFB), Icons.info_outline, Color.fromRGBO(54,105,214,1), shouldDismiss));
}

void showError(BuildContext context, String message,{bool shouldDismiss=true}) {
Timer.run(() => _showAlert(context,message, Color(0xFFFDE2E1), Icons.error_outline, Colors.red, shouldDismiss));
}

These are public methods, and we will be calling these methods wherever required.

To show a success toast, call the showSuccess method like below -

showSuccess(context, ‘Success Message’);

Final Code:

import ‘dart:async’;

import ‘package:flutter/cupertino.dart’;
import ‘package:flutter/material.dart’;
void showSuccess(BuildContext context, String message,{bool shouldDismiss=true}) {
Timer.run(() => _showAlert(context,message, Color(0xFFE2F8FF), CupertinoIcons.check_mark_circled_solid, Color.fromRGBO(91, 180, 107, 1), shouldDismiss));
}

void showInfo(BuildContext context, String message,{bool shouldDismiss=true}) {
Timer.run(() => _showAlert(context,message, Color(0xFFE7EDFB), Icons.info_outline, Color.fromRGBO(54,105,214,1), shouldDismiss));
}

void showError(BuildContext context, String message,{bool shouldDismiss=true}) {
Timer.run(() => _showAlert(context,message, Color(0xFFFDE2E1), Icons.error_outline, Colors.red, shouldDismiss));
}
void _showAlert(BuildContext context,String message, Color color, IconData icon, Color iconColor,bool shouldDismiss) {
showGeneralDialog(
context: context,
barrierDismissible: false,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
transitionDuration: const Duration(milliseconds: 200),
pageBuilder: (BuildContext buildContext, Animation animation, Animation secondaryAnimation) {
if(shouldDismiss){
Future.delayed(const Duration(seconds: 4), () {
Navigator.of(context, rootNavigator: true).pop(‘true’);
});
}
return Material(
type: MaterialType.transparency,
child: WillPopScope(
onWillPop: () async => false,
child: Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: const BorderRadius.vertical(top: Radius.circular(10), bottom: Radius.circular(10)),
color: color),
width: MediaQuery.of(context).size.width — 40,
height: MediaQuery.of(context).size.height / 9,
padding: const EdgeInsets.all(5),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(
icon,
size: 30,
color: iconColor,
),
const SizedBox(
width: 5,
),
Flexible(
child: Text(
message,
style: TextStyle(decoration: TextDecoration.none,color: Colors.black),
),
)
],
)),
),
),
),
);
});
}

That’s it! Thanks for reading!

If you enjoy Flutter and are keen on creating other fun stuff, here are two more things you can check out to supercharge your Flutter project:

A Flutter Card List:

A Flutter App Bar Dashboard:

DLT Labs is a trademark of DLT Global, Inc. Flutter is a trademark of Google LLC and its use here does not indicate endorsement or affiliation.

Author — Arun Kashyap Karri, DLT Labs

About the Author: Arun is an active learner and an enthusiastic Web / Mobile Developer. He has worked on Angular, Node.js, Flutter, RPA, IoT, Chatbots and few more technologies.

DLT Labs Logo
DLT Labs Logo

Written by

DLT Labs is a global leader in Distributed Ledger Technology and Enterprise Products. To know more, head over to: https://www.dltlabs.com/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store