TODO App Using Flutter

Introduction

 
In this documentation, I will cover how you can create a TODO App using Flutter even if you are a beginner or an expert in programming.
 

Create a TODO Flutter project and Run It

 
Step 1
 
Open Android Studio and click on the Create New Flutter Project option.
 
 
Step 2
 
Select Flutter Application and click on Next.
 
 
Step 3
 
Enter the name of the Project. Click on the Browse option.
 
 
 
Step 4
 
Navigate to Installed Flutter Path and click OK and click Next.
 
 
 
Step 5
 
Click Finish.
 
 
 
Step 6
 
Go to lib→main.dart File.
 
 
 
Step 7
 
Remove the existing code and paste the following code in main.dart File.
  1. import 'package:flutter/material.dart';  
  2. import 'package:flutter_todoapp_getx/screens/notes_list.dart';  
  3. import 'package:get/get.dart';  
  4. import 'package:get_storage/get_storage.dart';  
  5. void main() async {  
  6.     await GetStorage.init();  
  7.     runApp(MyApp());  
  8. }  
  9. class MyApp extends StatelessWidget {  
  10.     @override  
  11.     Widget build(BuildContext context) {  
  12.         return GetMaterialApp(  
  13.             title: 'Flutter Demo',  
  14.             theme: ThemeData(  
  15.                 primarySwatch: Colors.red,  
  16.                 visualDensity: VisualDensity.adaptivePlatformDensity,  
  17.             ),  
  18.             home: NoteList(),  
  19.         );  
  20.     }  
  21. }  
Explanation
 
Since we are going to use the navigation system of GETX and other alerts and snackbar that’s why we have converted MaterialApp to GetMaterialApp and we have provided our home screen as NoteList().
 
Step 8
 
Create a new Dart file in lib folder and name it as model.dart and paste the following code in model.dart File.
  1. class Note {  
  2.     String title;  
  3.     Note({  
  4.         this.title  
  5.     });  
  6.     factory Note.fromJson(Map < String, dynamic > json) => Note(  
  7.         title: json['title']);  
  8.     Map < String, dynamic > toJson() => {  
  9.         'title': title  
  10.     };  
  11. }  
 
Explanation:
 
The model.dart file creates the models of our TODO application. We will be only storing title as Note. So, we have created a class Note and provided a String title as parameter.
 
Step 9
 
Create a New Folder in lib Folder and name it as screens.
 
Step 10
 
Create a New Dart File in lib→screens Folder and name it as notes_list.dart and Paste the following code in notes_list.dart File.
  1. import 'package:flutter/material.dart';  
  2. import 'package:get/get.dart';  
  3. import 'package:flutter_todoapp_getx/screens/my_note.dart';  
  4. import 'controller.dart';  
  5. class NoteList extends StatelessWidget {  
  6.     @override  
  7.     Widget build(BuildContext context) {  
  8.         final NoteController nc = Get.put(NoteController());  
  9.         Widget getNoteList() {  
  10.             return Obx(  
  11.                 () => nc.notes.length == 0 ? Center(child: Image.asset('assets/lists.jpeg'), ) :  
  12.                 ListView.builder(  
  13.                     itemCount: nc.notes.length,  
  14.                     itemBuilder: (context, index) =>  
  15.                     Card(  
  16.                         child: ListTile(  
  17.                             title: Text(nc.notes[index].title,  
  18.                                 style: TextStyle(  
  19.                                     fontWeight: FontWeight.w500)),  
  20.                             leading: Text(  
  21.                                 (index + 1).toString() + ".",  
  22.                                 style: TextStyle(fontSize: 15),  
  23.                             ),  
  24.                             trailing: Wrap(children: < Widget > [  
  25.                                 IconButton(  
  26.                                     icon: Icon(Icons.create),  
  27.                                     onPressed: () =>  
  28.                                     Get.to(MyNote(index: index))),  
  29.                                 IconButton(  
  30.                                     icon: Icon(Icons.delete),  
  31.                                     onPressed: () {  
  32.                                         Get.defaultDialog(  
  33.                                             title: 'Delete Note',  
  34.                                             middleText: nc.notes[index].title,  
  35.                                             onCancel: () => Get.back(),  
  36.                                             confirmTextColor: Colors.white,  
  37.                                             onConfirm: () {  
  38.                                                 nc.notes.removeAt(index);  
  39.                                                 Get.back();  
  40.                                             });  
  41.                                     })  
  42.                             ])),  
  43.                     )  
  44.                 ),  
  45.             );  
  46.         }  
  47.         return SafeArea(  
  48.             child: Scaffold(  
  49.                 backgroundColor: Colors.white,  
  50.                 appBar: AppBar(  
  51.                     centerTitle: true,  
  52.                     title: Text('Todo App'),  
  53.                 ),  
  54.                 floatingActionButton: FloatingActionButton(  
  55.                     child: Icon(Icons.add),  
  56.                     onPressed: () {  
  57.                         Get.to(MyNote());  
  58.                     },  
  59.                 ),  
  60.                 body: Container(  
  61.                     child: Padding(  
  62.                         padding: EdgeInsets.all(5),  
  63.                         child: getNoteList()),  
  64.                 )));  
  65.     }  
  66. }  
Explanation
 
We will use our controller at first. Thereafter we are returning AppBar with the FloatingActionButton along with the body. We have added the functionality in our FloatingActionButton which eventually navigate to our my_note.dart class.
 
Step 11
 
Create a New Dart File in lib→screens Folder and name it as my_note.dart and Paste the following code in my_note.dart File. 
  1. import 'package:flutter/material.dart';  
  2. import 'package:get/get.dart';  
  3. import '../model.dart';  
  4. import 'controller.dart';  
  5. class MyNote extends StatelessWidget {  
  6.     int index;  
  7.     MyNote({  
  8.         this.index  
  9.     });  
  10.     @override  
  11.     Widget build(BuildContext context) {  
  12.         final NoteController nc = Get.find();  
  13.         String text = "";  
  14.         text = index == null ? " " : nc.notes[index].title;  
  15.         TextEditingController textEditingController = new TextEditingController(text: text);  
  16.         return SafeArea(  
  17.             child: Scaffold(  
  18.                 appBar: AppBar(  
  19.                     title: index == null ? Text('Create a New Note ') : Text('Update note'),  
  20.                 ),  
  21.                 body: Padding(  
  22.                     padding: EdgeInsets.all(15),  
  23.                     child: Container(  
  24.                         height: 500,  
  25.                         child: Column(  
  26.                             mainAxisAlignment: MainAxisAlignment.center,  
  27.                             crossAxisAlignment: CrossAxisAlignment.center,  
  28.                             children: < Widget > [  
  29.                                 Expanded(  
  30.                                     child: TextField(  
  31.                                         controller: textEditingController,  
  32.                                         autofocus: true,  
  33.                                         textCapitalization: TextCapitalization.sentences,  
  34.                                         decoration: InputDecoration(  
  35.                                             hintText: 'Create a new note!!',  
  36.                                             labelText: ' My Note',  
  37.                                             border: OutlineInputBorder(  
  38.                                                 borderSide: BorderSide(color: Colors.black87),  
  39.                                                 borderRadius: BorderRadius.circular(10)),  
  40.                                         ),  
  41.                                         style: TextStyle(fontSize: 20),  
  42.                                         keyboardType: TextInputType.text,  
  43.                                         maxLines: 5,  
  44.                                     ),  
  45.                                 ),  
  46.                                 Row(  
  47.                                     mainAxisAlignment: MainAxisAlignment.spaceEvenly,  
  48.                                     children: < Widget > [  
  49.                                         RaisedButton(  
  50.                                             onPressed: () {  
  51.                                                 Get.back();  
  52.                                             },  
  53.                                             child: Text('Cancel'),  
  54.                                             color: Colors.red,  
  55.                                         ),  
  56.                                         RaisedButton(  
  57.                                             onPressed: () {  
  58.                                                 if (index == null) {  
  59.                                                     nc.notes.add(Note(title: textEditingController.text));  
  60.                                                 } else {  
  61.                                                     var updatenote = nc.notes[index];  
  62.                                                     updatenote.title = textEditingController.text;  
  63.                                                     nc.notes[index] = updatenote;  
  64.                                                 }  
  65.                                                 Get.back();  
  66.                                             },  
  67.                                             child: index == null ? Text('Add') : Text('Update'),  
  68.                                             color: Colors.green, )  
  69.                                     ])  
  70.                             ],  
  71.                         ),  
  72.                     ),  
  73.                 )));  
  74.     }  
  75. }  
Explanation
 
We have created a variable ‘index’ which helps in updating our Note List. We have also created a TextField for the creation of Note and TextFieldController for updating the text in Note. Now here my_note class returns the AppBar along with the index logic if it is null then the text on the AppBar will create a new Note else will update the Note.
 
Step 12
 
Create a New Dart File in lib→screens Folder and name it as controller.dart and paste the following code in controller.dart file. 
  1. import 'package:get/get.dart';  
  2. import 'package:get_storage/get_storage.dart';  
  3. import '../model.dart';  
  4. class NoteController extends GetxController {  
  5.     var notes = List < Note > ().obs;  
  6.     void add(Note n) {  
  7.         notes.add(n);  
  8.     }  
  9.     @override  
  10.     void onInit() {  
  11.         List storedNotes = GetStorage().read < List > ('notes');  
  12.         if (!storedNotes.isNull) {  
  13.             notes = storedNotes.map((e) => Note.fromJson(e)).toList().obs;  
  14.         }  
  15.         ever(notes, (_) {  
  16.             GetStorage().write('notes', notes.toList());  
  17.         });  
  18.         super.onInit();  
  19.     }  
  20. }  
Explanation
 
We have created a NoteController class that extends GetXController. Here we have created a variable note which will be storing list of Note data type and we have that observable. By making it observable our controller will be continuously be listening to the changes in Note. Also, we have created a method add that takes Note as parameter which will eventually add Note to our list.
 
Step 13
 
Create a New Folder in your project and name it as assets and add the following image as ‘lists.jpg’. 
Step 14
 
Add the following dependencies in your pubspec.yaml File.
 
 
 
Explanation
 
We have to import the above two packages get: and get_storage: and also, we are going to use some of the images, that’s why we have also imported assets folder under assets dependency.
 
Step 15
 
Use the emulator command to start the emulator, as an alternative to running your project or starting it through the AVD Manager.
 
Step 16
 
To create a new AVD:
  1. Open the AVD Manager by clicking Tools → AVD Manager.
  2. Click Create Virtual Device, at the bottom of the AVD Manager dialog.
  3. The Select Hardware page appears.
  4. Select a hardware profile, and then click Next.
  5. Select the system image for a particular API level, and then click Next.
  6. Change AVD properties as needed, and then click Finish.
Click Show Advanced Settings to show more settings, such as the skin.
 
The new AVD appears in the Your Virtual Devices page or the Select Deployment Target dialog.
 
References
 
 
Step 17
 
Run the app on your device. Click Run.
 
 
 
Step 18
 
All Set to go and you can view the output.
 
 
 
 

Conclusion

 
In this article, we discussed about how to create a TODO application using Flutter.