Notekeeper Application Using Flutter

Flutter is an open-source cross-platform mobile development framework developed by Google. Apps for which are written in Dart. Flutter comes pre-equipped with Material Design components which makes it easy to create apps with good look and feel. In Flutter everything is a Widget of either stateless or stateful.

Summary:

  • This blog is a walkthrough of the process to make a NOTE-KEEPING application using Flutter. To Start off, we will be learning some basics fundamentals of Flutter.
  • Here we will understand step by step guide of this process. And at the end will see working example for the same.

Prerequisites:
You can start flutter if you have experience in the following categories:-

  • If you have worked with Android or iOS native or React Native or Xamarin or Ionic or another mobile development framework
  • If you have knowledge about Dart language
  • If you have worked with Object Oriented Languages such as Java, C++ and I’m comfortable with OOP concepts such as Classes, Objects, Methods

Installations:
One of the best things about Flutter is that it lets you use your favourite IDE for development. It has first class support for Android Studio, IntelliJ IDEA and VS Code. Well, my favourite IDE is VS Code because it is minimalist and feels very lightweight.

Install Visual Studio Code
VS Code is a light-weight editor with Flutter app execution and debug support.

Install the Flutter and Dart plugins

  1. Start VS Code.
  2. Invoke View > Command Palette….
  3. Type “install”, and select Extensions: Install Extensions.
  4. Type “flutter” in the extensions search field, select Flutter in the list, and click install. This also installs the required Dart plugin.

Validate your setup with the Flutter Doctor

  1. Invoke View > Command Palette….
  2. Type “doctor”, and select the Flutter: Run Flutter Doctor.
  3. Review the output in the OUTPUT pane for any issues.

Next Step
Take Flutter for a test drive: create a first project, run it, and experience “hot reload”.

Creating the app

  1. Invoke View > Command Palette.
  2. Type “flutter”, and select the Flutter: New Project.
  3. Enter a project name, such as Flutter_Demos, and press Enter.
  4. Create or select the parent directory for the new project folder.
  5. Wait for project creation to complete and the main.dart file to appear.
-flutter doctor

Once you are ready you can run the following command to make sure setup is done.
Now, you will get the output.
In this article, we will see how to write code in main.dart file. By default, it contains some sample code, delete all the contents.
In this article, I will demonstrate using SQLite in Flutter.

Why SQLite?
SQLite is one of the most popular ways to store data locally. For this article, we will be using the package sqflite to connect with SQLite. Sqflite is one of the most used and up to date packages for connecting to SQLite databases in Flutter.

Our Example

For illustration, consider the following,

  • The app has two separate screens: a note_list and a note_detail (represented by the NoteList and NoteDetail respectively).
  • The note_list screen includes a custom app bar and a scrolling view of many list items. It also include a floating action button to add a new note in the list.
  • The note_detail screen includes the detail of the node to be created. It includes the priority order of the note to be created and the title and description of the note.
  • The app has a database_helper class which includes all details of the operations performed in backend database.

Here’s the app visualized as a widget tree

  1. Following is a code snippet from pubspec.yaml with the required dependencies listed. Add them, save the file and use flutter command “flutter packages get” to resolve the newly added dependencies. You can get the latest version from pub.
dependencies:
flutter:
sdk: flutter
sqflite: latest
path_provider: latest
intl: latest

NOTE: We use the path_provider package to get the commonly used location such as TemporaryDirectory and ApplicationDocumentsDirectory.

Now, Let’s start to code for our Note keeper application. As mentioned above we have two screens and we named it as notedetail and notelist. We have also created a model class name note and a databasehelper class. Creating a class for the notes.
First, we need to create

  • A Model class
  • A Database Helper class
  • Create a Singletons objects for database as well as database helper class.
  • Write code for performing the insert, update, fetch and delete operations.

Here we have created a Model class Note.

class Note {
int _id;
String _title;
String _description;
String _date;
int _priority;
Note(this._title, this._date, this._priority, [this._description]);
Note.withId(this._id, this._title, this._date, this._priority, [this._description]);
int get id => _id;
String get title => _title;
String get description => _description;
int get priority => _priority;
String get date => _date;
set title(String newTitle) {
if (newTitle.length <= 255) {
this._title = newTitle;
}
}
set description(String newDescription) {
if (newDescription.length <= 255) { this._description = newDescription; } } set priority(int newPriority) { if (newPriority >= 1 && newPriority <= 2) {
this._priority = newPriority;
}
}
set date(String newDate) {
this._date = newDate;
}
// Convert a Note object into a Map object
Map<String, dynamic> toMap() {
var map = Map<String, dynamic>();
if (id != null) {
map['id'] = _id;
}
map['title'] = _title;
map['description'] = _description;
map['priority'] = _priority;
map['date'] = _date;
return map;
}
// Extract a Note object from a Map object
Note.fromMapObject(Map<String, dynamic> map) {
this._id = map['id'];
this._title = map['title'];
this._description = map['description'];
this._priority = map['priority'];
this._date = map['date'];
}
}

Click here to access the full code.

Further, after creating the model class, we have created the DatabaseHelper class. Import the required packages for the DatabaseHelper class, also import the package note.dart.
Then we will have to create the single object of the class. Singleton instance of the class means the instance will be initialized only once throughout our application.
Now we will write the code for creating the database and perform various operations like Insert, Update, Delete & Fetch.

import 'package:sqflite/sqflite.dart';
import 'dart:async';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_app/models/note.dart';
class DatabaseHelper {
static DatabaseHelper _databaseHelper; // Singleton DatabaseHelper
static Database _database;
// Singleton Database
String noteTable = 'note_table';
String colId = 'id';
String colTitle = 'title';
String colDescription = 'description';
String colPriority = 'priority';
String colDate = 'date';
DatabaseHelper._createInstance(); // Named constructor to create instance of
DatabaseHelper
factory DatabaseHelper() {
if (_databaseHelper == null) {
_databaseHelper = DatabaseHelper._createInstance(); // This is executed only once,
singleton object
}
return _databaseHelper;
}
Future get database async {
if (_database == null) {
_database = await initializeDatabase();
}
return _database;
}
Future initializeDatabase() async {
// Get the directory path for both Android and iOS to store database.
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path + 'notes.db';

Click here to access the full code.

Now let us connect our database with our UI.
Let us first import all the packages for our note_list.dart file and do the same for the note_detail.dart file.
For the NoteList which will be used for displaying the list of the notes.

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_app/models/note.dart';
import 'package:flutter_app/utils/database_helper.dart';
import 'package:flutter_app/screens/note_detail.dart';
import 'package:sqflite/sqflite.dart';

The class NoteList will be used to display the notes which are added on clicking the (addnote) button, on clicking the button a new screen notedetail will appear in which we have to set the options to select the priority of the notes to be added, add a title for the notes and write the description of the note.
In the class NoteList, we have created a button to add new notes, a listview to display the notes which also includes the priority of the notes in which we have set two different methods to set the color and icon of the note according to their priority (high & low). We can also update the note by clicking on the notes using the ontap gesturedetector & the note can also be deleted on clicking the trailing delete icon added on the note list.

The sample code for the above description is as follows:
Click here to access the full code.

class NoteList extends StatefulWidget {
@override
State createState() {
return NoteListState();
}
}
class NoteListState extends State {
DatabaseHelper databaseHelper = DatabaseHelper();
List noteList;
int count = 0;
@override
Widget build(BuildContext context) {
if (noteList == null) {
noteList = List();
updateListView();
}

Now, let us create the screen to add the details of the note. We have created a NoteDetail class which will be used to add new notes, update existing notes and delete the details of notes.
The NoteDetail class will contain the elements to set the priority (high/low), a textfield to insert and update the content of the title field of notes, another textfield to insert and update the content of the description field of notes, save & delete button to save & delete the notes.
Let us first import all the packages for our note_detail.dart file.
The NoteDetail class will contain the elements to set the priority (high/low), a textfield to insert and update the content of the title field of notes, another textfield to insert and update the content of description field of notes, save & delete button to save & delete the notes.
Let us first import all the packages for our note_detail.dart file.

import 'package:flutter/material.dart';
import 'package:flutter_app/models/note.dart';
import 'package:flutter_app/utils/database_helper.dart';
import 'package:intl/intl.dart';

The sample code for the above description is as follows.

class NoteDetail extends StatefulWidget {
final String appBarTitle;
final Note note;
NoteDetail(this.note, this.appBarTitle);
@override
State createState() {
return NoteDetailState( this.note , this.appBarTitle);
}
}

Click here to access the full code.

Now, let us update the main.dart file which will be as follows.

import 'package:flutter/material.dart';
import 'package:flutter_app/screens/note_list.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'NoteKeeper',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue
),
home: NoteList(),
);
}
}

Let's create the next BIG thing together

CREDITS

Dhara Patel

MENTOR

Bhumin Naik