Skip to main content

Alert Dialog in Flutter


Introduction

Alert Dialogs are often needed to notify users if they are pressing back button while making payment or deleting/removing any item. So to deal with following events and confirm the users of your app whether they are sure of there decision or not, Alert Dialogs are most important part of our app.

Contents

  1. Project Setup
  2. Code
  3. Logic
  4. Result

Project Setup

As a starter project of our app I am providing a very simple ToDo app with Add/Delete Functionality. So if you want to continue with your own code you can or else  here is the code I will proceed.
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Todo App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: TodoApp(),
    );
  }
}

class TodoApp extends StatefulWidget {
  const TodoApp({Key? key}) : super(key: key);

  @override
  _TodoAppState createState() => _TodoAppState();
}

class _TodoAppState extends State<TodoApp> {
  List<String> tasks = ["Add tasks"];
  TextEditingController textBoxController = TextEditingController();
  final _formKey = GlobalKey<FormState>();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'TODO APP',
          style: TextStyle(
            color: Colors.white,
            fontSize: 48.0,
            fontWeight: FontWeight.w700,
          ),
        ),
        centerTitle: true,
      ),
      body: Column(
        children: <Widget>[
          Form(
            key: _formKey,
            child: TextFormField(
              controller: textBoxController,
              validator: (value) {
                if (value!.isEmpty) return 'No task to add';
              },
              decoration: InputDecoration(
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(
                    15.0,
                  ),
                ),
                hintText: 'Add task',
              ),
            ),
          ),
          ElevatedButton(
            onPressed: () {
              setState(() {
                bool valid = _formKey.currentState!.validate();
                if (valid) {
                  tasks.add(textBoxController.text);
                  textBoxController.clear();
                }
              });
            },
            child: Text(
              'ADD',
              style: TextStyle(
                color: Colors.white,
                fontSize: 32.0,
                fontWeight: FontWeight.w700,
              ),
            ),
            style: ElevatedButton.styleFrom(
              primary: Colors.blue[400],
            ),
          ),
          Container(
            child: ListView.builder(
              shrinkWrap: true,
              physics: BouncingScrollPhysics(),
              itemCount: tasks.length,
              itemBuilder: (BuildContext context, int index) {
                return Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: ListTile(
                    tileColor: Colors.amber[50],
                    leading: Text(
                      '${index + 1}.',
                    ),
                    title: Text(
                      tasks[index],
                    ),
                    trailing: IconButton(
                      onPressed: () {
                        setState(() {
                          tasks.removeAt(index);
                        });
                      },
                      icon: Icon(
                        Icons.delete,
                      ),
                    ),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}
 Copy the whole code and paste in your main.dart file.
Now run the app. If everything done correctly the app should look like
Starter App

Code

The code here is pretty simple. I have used a TextFormField where when task is typed. After that user has to press the Add button which validates and if the text input is not empty the task is added to tasks list. Now after that I have used a ListView.builder which generates ListTile and each tile contains the index of task and the task itself. Besides that I have added a Delete button (which is an IconButton) to ListTile. When tapped the task is deleted and ListView is updated as you can see.
So our aim is to confirm from user that whether he wants to delete the task or not.
Let's Begin

Logic

Come to very bottom of the provide code and as you can see a ListTile with some fields in it.
ListTile(
  tileColor: Colors.amber[50],
  leading: Text(
    '${index + 1}.',
  ),
  title: Text(
    tasks[index],
  ),
  trailing: IconButton(
    onPressed: () {
      setState(() {
        tasks.removeAt(index);
      });
    },
    icon: Icon(
      Icons.delete,
    ),
  ),
),

Here in the trailing field as said I have made an IconButton. So when pressed simply the task is deleted.  Here we are going to add an AlertDialog which will say that if the user wants to delete the task or not. For them who are using there own code you can go as the implementation remains same.
Come to onPressed field of IconButton.
We will add here showDialog code. 
showDialog(
  context: context,
  builder: (BuildContext context) {},
);

showDialog displays a Material Dialog above the current contents of app. To us a Dialog.

In the official documentation you can read in detail each and every field here.
In the builder section we are going to return an AlertDialog. AlertDialog as name says alerts the user. So we are going to alert the users. Inside the curly braces of builder function write
return AlertDialog();

Here in AlertDialog we are going to use the following fields.
  1. title It accepts a widget and here generally a Text widget is placed about the action user is performing.
  2. actions[]: This is row of widgets displayed at the end of AlertDialog.We are going to provide two options, YES or NO
So lets begin by providing the title as follows.
title: Text("Do you really want to delete this task?"),

And in the actions let's provide two options.
actions: [
  TextButton(
    onPressed: () {},
    child: Text('Yes'),
  ),
  TextButton(
    onPressed: () {},
    child: Text('No'),
  ),
],

In the onPressed section we are going to perform our task.
Cut the setState function used below the showDialog and paste it into the Yes option inside the onPressed function.
onPressed: () {
  setState(() {
    tasks.removeAt(index);
  });
},

Now the showDialog works by Navigation you most probably used for going from one screen to other in Flutter. Show to close the Alert Dialog we need to Navigate back to our screen. So add 
Navigator.pop(context);

both to onPressed function of both buttons.
Our code is complete.

Result

Run the app
Todo app finish
Congrats you learnt Alert Dialogs. You can edit the code and even design the AlertDialogs according to you. If you want the tutorials about customised alert dialogs comment below.
The final code is here.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Todo App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: TodoApp(),
    );
  }
}

class TodoApp extends StatefulWidget {
  const TodoApp({Key? key}) : super(key: key);

  @override
  _TodoAppState createState() => _TodoAppState();
}

class _TodoAppState extends State<TodoApp> {
  List<String> tasks = ["Add tasks"];
  TextEditingController textBoxController = TextEditingController();
  final _formKey = GlobalKey<FormState>();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'TODO APP',
          style: TextStyle(
            color: Colors.white,
            fontSize: 48.0,
            fontWeight: FontWeight.w700,
          ),
        ),
        centerTitle: true,
      ),
      body: Column(
        children: <Widget>[
          Form(
            key: _formKey,
            child: TextFormField(
              controller: textBoxController,
              validator: (value) {
                if (value!.isEmpty) return 'No task to add';
              },
              decoration: InputDecoration(
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(
                    15.0,
                  ),
                ),
                hintText: 'Add task',
              ),
            ),
          ),
          ElevatedButton(
            onPressed: () {
              setState(() {
                bool valid = _formKey.currentState!.validate();
                if (valid) {
                  tasks.add(textBoxController.text);
                  textBoxController.clear();
                }
              });
            },
            child: Text(
              'ADD',
              style: TextStyle(
                color: Colors.white,
                fontSize: 32.0,
                fontWeight: FontWeight.w700,
              ),
            ),
            style: ElevatedButton.styleFrom(
              primary: Colors.blue[400],
            ),
          ),
          Container(
            child: ListView.builder(
              shrinkWrap: true,
              physics: BouncingScrollPhysics(),
              itemCount: tasks.length,
              itemBuilder: (BuildContext context, int index) {
                return Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: ListTile(
                    tileColor: Colors.amber[50],
                    leading: Text(
                      '${index + 1}.',
                    ),
                    title: Text(
                      tasks[index],
                    ),
                    trailing: IconButton(
                      onPressed: () {
                        showDialog(
                          context: context,
                          builder: (BuildContext context) {
                            return AlertDialog(
                              title: Text(
                                  "Do you really want to delete this task?"),
                              actions: [
                                TextButton(
                                  onPressed: () {
                                    setState(() {
                                      tasks.removeAt(index);
                                    });
                                    Navigator.pop(context);
                                  },
                                  child: Text('Yes'),
                                ),
                                TextButton(
                                  onPressed: () {
                                    Navigator.pop(context);
                                  },
                                  child: Text('No'),
                                ),
                              ],
                            );
                          },
                        );
                      },
                      icon: Icon(
                        Icons.delete,
                      ),
                    ),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

Comments

Popular posts from this blog

Flutter | Material Banner Tutorial

In this tutorial, we will create and display Material Banner in Flutter . Material Banners are displayed at the top of the screen . User interaction is required to dismiss the banner . Material Banner Material Banner alerts the user about action and p rovides some actions for the user to take . In brief, it alerts the user about an issue and the user address the issue . The user should dismiss the banner to remove it from the screen else it will be active. Syntax  ScaffoldMessenger.of(context).showMaterialBanner(MaterialBanner( content: content, actions: actions)) Code Here is our starting class. It is a stateless class and we will display a banner when the Button is pressed. class SnackBarTutorial extends StatelessWidget { const SnackBarTutorial({Key ? key}) : super ( key: key); @ override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text( "Material Banner"

How to create Snackbars in Flutter | Snackbar Tutorial

In this article, we will create and display different types of SnackBars in Flutter.  SnackBars in Flutter SnackBars are used to briefly display some information or inform the user about an action. For instance, when a user deletes a mail or message you may want to inform the user about the action. Also, the user can undo the action he performed by the undo button in the Snackbar . Syntax For creating a SnackBar, we use the following code. ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: content)); Inside the content field of SnackBar, we will pass the content. Any content can be passed inside it, but in practice, small messages with or without a button. Example Simple SnackBar class SnackBarTutorial extends StatelessWidget {   const SnackBarTutorial({Key? key}) : super (key: key);   @override   Widget build(BuildContext context) {     return

Flutter: DatePicker Tutorial both with Material and Cupertino Style

Introduction DatePicker is very important when you want the user to pick his / her date of birth or something else. In Flutter, implementing DatePicker is very easy and we will implement DatePicker in both Android or Material style and Cupertino or IOS style.  Table of contents Approach Project Setup Material Style DatePicker Cupertino Style DatePicker Conclusion Approach Flutter has widgets for everything and even for DatePicker. DatePicker widget is loaded with all needed animation and colours. So implementation is very easy.  Project Setup No extra plugins are required for this project and you can continue with your existing project. Here is the starting code. class DatePickerTutorial extends StatefulWidget { const DatePickerTutorial({Key? key}) : super (key: key); @ override _DatePickerTutorialState createState() => _DatePickerTutorialState(); } class _DatePickerTutorialState extends State<DatePick