Lab 4 - My To Do List
Lab 4 - My To Do List
The app we are going to make is an offline diary that lets users record the activities
they did during the day. Each of these activities will be called a “journal” or an “item”.
The app has a floating button that can be used to show a bottom sheet. That bottom
sheet contains 2 text fields corresponding to “title” and “description”. These text fields
are used to create a new “item” or update an existing “item”.
The saved “items” are fetched from the SQLite database and displayed with a list
view. There are an update button and a delete button associated with each “item”.
Main Page
I. In this main page, users can add
their activities by tapping on the +
button.
II. After that user can their new
activity by entering the title and
description in text area provided.
III. Tap on Create New and all the
details will be saved into the
database.
IV. This Project also allowed user to
edit and remove activities that has
been stored in the database.
Let’s get started
1. Create a new Flutter project. In the lib folder, add a new file named
sql_helper.dart.
2. In your terminal type (To install sqlite):
flutter pub add sqflite
import 'package:flutter/foundation.dart';
class SQLHelper {
title TEXT,
description TEXT,
""");
// created_at: the time that the item was created. It will be automatically handled by SQLite
return sql.openDatabase(
'activity.db',
version: 1,
await createTables(database);
},
);
}
conflictAlgorithm: sql.ConflictAlgorithm.replace);
return id;
// The app doesn't use this method but I put here in case you want to see it
//}
// Update an item by id
final data = {
'title': title,
'description': descrption,
'createdAt': DateTime.now().toString()
};
final result =
return result;
// Delete
try {
} catch (err) {
import 'package:flutter/material.dart';
import 'sql_helper.dart';
void main() {
runApp(const MyApp());
@override
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.deepOrange,
),
@override
// All journals
setState(() {
_journals = data;
_isLoading = false;
});
}
@override
void initState() {
super.initState();
if (id != null) {
final existingJournal =
_titleController.text = existingJournal['title'];
_descriptionController.text = existingJournal['description'];
showModalBottomSheet(
context: context,
elevation: 5,
isScrollControlled: true,
padding: EdgeInsets.only(
top: 15,
left: 15,
right: 15,
// this will prevent the soft keyboard from covering the text fields
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextField(
controller: _titleController,
),
const SizedBox(
height: 10,
),
TextField(
controller: _descriptionController,
),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () async {
if (id == null) {
await _addItem();
if (id != null) {
await _updateItem(id);
}
// Clear the text fields
_titleController.text = '';
_descriptionController.text = '';
Navigator.of(context).pop();
},
],
),
));
await SQLHelper.createItem(
_titleController.text, _descriptionController.text);
_refreshJournals();
await SQLHelper.updateItem(
_refreshJournals();
// Delete an item
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
));
_refreshJournals();
@override
return Scaffold(
appBar: AppBar(
),
body: _isLoading
? const Center(
child: CircularProgressIndicator(),
: ListView.builder(
itemCount: _journals.length,
color: Colors.orange[200],
child: ListTile(
title: Text(_journals[index]['title']),
subtitle: Text(_journals[index]['description']),
trailing: SizedBox(
width: 100,
child: Row(
children: [
IconButton(
),
IconButton(
onPressed: () =>
_deleteItem(_journals[index]['id']),
),
],
),
)),
),
),
floatingActionButton: FloatingActionButton(
),
);