import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: NotesListScreen(),
);
}
}
class NotesListScreen extends StatefulWidget {
const NotesListScreen({super.key});
@override
State<NotesListScreen> createState() => _NotesListScreenState();
}
class _NotesListScreenState extends State<NotesListScreen> {
late Database db;
List<String> notes = [];
@override
void initState() {
super.initState();
_initDb();
}
Future<void> _initDb() async {
final databasePath = await getDatabasesPath();
final path = join(databasePath, 'notes.db');
db = await openDatabase(
path,
version: 1,
onCreate: (db, version) async {
await db.execute('''
CREATE TABLE notes(
id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT
)
''');
},
);
await _loadNotes();
}
Future<void> _loadNotes() async {
final List<Map<String, dynamic>> maps = await db.query('notes');
setState(() {
notes = maps.map((map) => map['content'] as String).toList();
});
}
Future<void> _addNote() async {
final TextEditingController controller = TextEditingController();
final result = await showDialog<String?>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Add Note'),
content: TextField(
controller: controller,
autofocus: true,
decoration: const InputDecoration(hintText: 'Enter note content'),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancel'),
),
TextButton(
onPressed: () {
final text = controller.text.trim();
if (text.isNotEmpty) {
Navigator.pop(context, text);
}
},
child: const Text('Save'),
),
],
),
);
if (result != null && result.isNotEmpty) {
await db.insert('notes', {'content': result});
await _loadNotes();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Notes List'),
),
body: ListView.builder(
itemCount: notes.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(notes[index]),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: _addNote,
child: const Icon(Icons.add),
),
);
}
}
This app uses the sqflite package to manage a local SQLite database. In initState, it opens or creates the database file and the notes table if it doesn't exist. Then it loads all saved notes into a list.
The _addNote method shows a dialog with a text field for the user to enter a new note. When saved, the note is inserted into the database, and the list is refreshed to show the new note immediately.
The UI uses a ListView to display notes and a floating button with a plus icon to add new notes. This simple structure helps beginners understand how to connect UI with persistent local storage.