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
- Project Setup
- Code
- Logic
- 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
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.
- title: It accepts a widget and here generally a Text widget is placed about the action user is performing.
- 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
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
Post a Comment
If you have any problem or doubt please comment.