Thanks to the advantages of mobile, there are quite a few types of Flutter dialogs. Below are a few commonly used styles of dialogs.
The layout of the Scaffold component to prepare is as follows:
Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Dialog"), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ElevatedButton( onPressed: _alertDailog, child: const Text("alert dialog - AlertDialog"), ), ElevatedButton( onPressed: _simpleDialog, child: const Text("select dialog - SimpleDialog"), ), ElevatedButton( onPressed: _modalBottomSheet, child: const Text("modal dialog - ModalBottomSheet"), ), ElevatedButton( onPressed: _toast, child: const Text("toast dialog - Toast"), ), ]), ), ); }
AlertDialog (Prompt Dialog)#
The prompt dialog looks like this:
//alertDailog (note the async) void _alertDailog() async { var result = await showDialog( context: context, barrierDismissible: false, // Disallow clicking the gray background to dismiss builder: (context) { return AlertDialog( title: const Text("I am alertDialog"), content: Text("I am the body of the Dialog"), actions: [ TextButton( onPressed: () { print("ok"); // Close the dialog, just return directly Navigator.pop(context, true); }, child: const Text("Confirm")), TextButton( onPressed: () { print("cancel"); Navigator.pop(context, false); }, child: const Text("Cancel")), ], ); }); print(result); }
SimpleDialog#
You can place any components inside a normal dialog, which can be used for selection functionality.
void _simpleDialog() async { var res = await showDialog( context: context, builder: (context) { return SimpleDialog( title: const Text("Please select a language"), children: [ SimpleDialogOption( onPressed: () { Navigator.pop(context, "Chinese"); }, child: const Text("Chinese"), ), const Divider(), SimpleDialogOption( onPressed: () { Navigator.pop(context, "English"); }, child: const Text("English"), ), const Divider(), SimpleDialogOption( onPressed: () { Navigator.pop(context, "Japanese"); }, child: const Text("Japanese"), ) ], ); }); print(res); }
showModalBottomSheet (Bottom Modal Sheet)#
First, let's see the effect:
Here, we will demonstrate with a shopping cart example:
void _modalBottomSheet() async { var res = await showModalBottomSheet( context: context, builder: (context) { return SizedBox( height: 250, child: Column( children: [ Padding( padding: const EdgeInsets.fromLTRB(20, 0, 20, 0), child: Row( children: [ const Padding( padding: EdgeInsets.fromLTRB(0, 0, 10, 0), child: Text( "Color:", style: TextStyle(fontWeight: FontWeight.bold), ), ), Padding( padding: const EdgeInsets.all(10), child: ElevatedButton( onPressed: () { Navigator.pop(context, "Red"); }, style: ButtonStyle( backgroundColor: const MaterialStatePropertyAll( Color.fromARGB(255, 254, 80, 42), ), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(50)), ), ), child: const Text("Red"), ), ), Padding( padding: const EdgeInsets.all(10), child: ElevatedButton( onPressed: () { Navigator.pop(context, "Yellow"); }, style: ButtonStyle( backgroundColor: const MaterialStatePropertyAll( Color(0x00000ccc), ), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(50)), ), ), child: const Text("Yellow"), ), ), Padding( padding: const EdgeInsets.all(10), child: ElevatedButton( onPressed: () { Navigator.pop(context, "Blue"); }, style: ButtonStyle( backgroundColor: const MaterialStatePropertyAll( Color(0x00000ccc), ), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(50)), ), ), child: const Text("Blue"), ), ), ], ), ), Padding( padding: const EdgeInsets.fromLTRB(20, 0, 20, 0), child: Row( children: [ const Padding( padding: EdgeInsets.fromLTRB(0, 0, 10, 0), child: Text( "Size:", style: TextStyle(fontWeight: FontWeight.bold), ), ), Padding( padding: const EdgeInsets.all(10), child: ElevatedButton( onPressed: () { Navigator.pop(context, "XL"); }, style: ButtonStyle( backgroundColor: const MaterialStatePropertyAll( Color.fromARGB(255, 254, 80, 42), ), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(50)), ), ), child: const Text("XL"), ), ), Padding( padding: const EdgeInsets.all(10), child: ElevatedButton( onPressed: () { Navigator.pop(context, "XML"); }, style: ButtonStyle( backgroundColor: const MaterialStatePropertyAll( Color(0x00000ccc), ), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(50)), ), ), child: const Text("XML"), ), ), Padding( padding: const EdgeInsets.all(10), child: ElevatedButton( onPressed: () { Navigator.pop(context, "XXL"); }, style: ButtonStyle( backgroundColor: const MaterialStatePropertyAll( Color(0x00000ccc), ), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(50)), ), ), child: const Text("XXL"), ), ), ], ), ), SizedBox( height: 100, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.all(10), child: ElevatedButton( onPressed: () { Navigator.pop(context, "ok"); }, style: ButtonStyle( backgroundColor: const MaterialStatePropertyAll( Colors.red, ), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), ), ), child: const SizedBox( width: 150, height: 40, child: Center( child: Text("Add to Cart"), ), ), ), ), Padding( padding: const EdgeInsets.all(10), child: ElevatedButton( onPressed: () { Navigator.pop(context, "ok purchase"); }, style: ButtonStyle( backgroundColor: const MaterialStatePropertyAll( Colors.orange, ), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), ), ), child: const SizedBox( width: 150, height: 40, child: Center( child: Text("Buy Now"), ), ), ), ), ], ), ), ], ), ); }); print(res); }
Fluttertoast (Toast Message)#
Note: Flutter does not come with a built-in toast, you need to install one from the repository.
flutter pub add fluttertoast
Using toast:
void _toast() { Fluttertoast.showToast( msg: "This is a toast", toastLength: Toast.LENGTH_SHORT, // Effective on Android platform (duration of toast display) gravity: ToastGravity.CENTER, // Position timeInSecForIosWeb: 1, // Display time for iOS and web backgroundColor: Colors.red, // Background color textColor: Colors.red, // Text color fontSize: 16.0, // Text font size ); }
Effect:
Custom Dialog#
In Flutter, you can add a custom Widget by using the builder function in
showDialog
.// Custom Dialog void _myDialog() async { var res = await showDialog( context: context, // Clicking the gray background will not dismiss barrierDismissible: false, builder: (context) { // Using custom Dialog return MyDialog( title: "kano", content: "kanokano.cn", onTap: () { // Asynchronous event Navigator.pop(context, 'Closed'); }, ); }); print(res); }
MyDialog.dart
import 'package:flutter/material.dart'; class MyDialog extends Dialog { late String title; late String content; late Function()? onTap; MyDialog( {Key? key, required this.title, required this.content, required this.onTap}) : super(key: key); @override Widget build(BuildContext context) { // Material component can set the background to transparent, so we use it return Material( // Set to transparent (also activates the function to close the dialog by clicking outside) type: MaterialType.transparency, // Clicking the gray background will not dismiss child: Center( // Wrap in a Center to avoid full-screen coverage by the dialog child: Container( height: 300, width: 300, padding: const EdgeInsets.all(10), color: Colors.white, child: Column( children: [ Stack( children: [ Align( alignment: Alignment.topLeft, child: Text(title), ), Align( alignment: Alignment.topRight, // InkWell has various click and interaction events child: InkWell( onTap: onTap, child: const Icon(Icons.close), ), ), ], ), const Divider(), Container( padding: const EdgeInsets.all(10), width: double.infinity, child: Text(content), ) ], )), ), ); } }