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: 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...

Flutter: DraggableScrollableSheet widget Tutorial

Introduction In this tutorial, we are going to learn about the DraggableScrollableSheet widget. It is a widget that responds to user gestures. When the user drags from the bottom of the screen in the upward direction, the widget opens up and when scrolls down the widget close. The final app will look as follows  Final App DraggableScrollableSheet It is a widget that scrolls up and down of the viewport or screen according to the user's screen gestures. This widget becomes handy when you want to give some extra details which are lengthy content but don't want to navigate to a new screen. You might have come across many apps that implement the same thing. So let us learn to implement DraggableScrollableSheet in our own app. Approach The approach of our project is very simple. In our app, we are going to display some names of countries with the help of the  ListView.builder  and Li...

Flutter : Image Picker Tutorial | Pick single image from Gallery

Introduction In this tutorial, we will create an image picker and display the content on the screen . I mage Picker picks a file from the Storage or Camera and stores it in an XFile object. Implementation Install dependency We will first need the image_picker dependency . To install it, add the following dependency to pubspec.yaml file. image_picker: ^0.8.4+3 Then click on Get Packages in your IDE or run the following command on your Terminal / Command Prompt. flutter pub get Example Import the dependency in your dart file. import 'package:image_picker/image_picker.dart' ; Syntax Image picking is a future task . So we need to await the image picking . Here is the syntax. await _picker.pickImage( source : ImageSource.gallery); Here we have provided the source from the gallery . We can also provide the source as a Camera using the following syntax. await _picker.pickImage( source : Ima...