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

Animated Navigation in Flutter

  Introduction By default, Flutter has no animation when navigating from one Screen to another Screen. But in this tutorial, we are going to learn how to animate the Screen Transition.   Introduction By default, Flutter has no animation when navigating from one Screen to another Screen. But in this tutorial, we are going to learn how to animate the Screen Transition. Table of Contents Project Setup Code Result Project Setup Before directly applying to your existing project, practice the code in some example projects. For this tutorial, we are going to name our project screen_animation_tutorial. Open in VSCode or Android Studio. After that, we will make two Screens. The first Screen will be the Starting screen and the next Screen will be the Final Screen. So go ahead and create two dart files under the lib folder. The main.dart file code should look like this Dart import 'package:flutter/material.dart'; import 'package:screen_animation_tutorial/start_screen.dart'; void ...

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) { ...

Flutter : Screen Animation tutorial

In this tutorial, we will learn how to perform animations while navigating from one screen to another. We will not require any other dependency to be installed. We will demonstrate the following example. So let's start. Approach Instead of using the default MaterialPageRoute, we will use the PageRouteBuilder. PageRouteBuilder provides all the functionalities like duration, type of animation. Syntax The syntax for PageRouteBuilder is as follows. PageRouteBuilder( transitionDuration: const Duration( seconds: 1 ), pageBuilder: (context, animation, secondaryAnimation) { return const SecondScreen(); }, ), The parameters and fields are self-explanatory. Code Let us code our First Screen of the app. class FirstScreen extends StatelessWidget { const FirstScreen({Key ? key}) : super ( key: key); @ override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text( "First...