โ Why Persist Data?
If you close the app now, all tasks disappear โ that’s because your Todo list only lives in memory.
To fix this, weโll use Shared Preferences to save the list to local storage and reload it when the app starts.
๐งฐ What is Shared Preferences?
Shared Preferences is a Flutter plugin for simple key-value storage on the device.
Itโs ideal for:
- Small amounts of user data
- App settings
- Simple lists (like our Todo list)
โ๏ธ When to Use It (and When Not To)
โ Great For:
- Saving booleans, strings, numbers
- Small app data
- User preferences
โ Avoid for:
- Complex data structures
- Sensitive data (not encrypted)
- Large datasets โ use
Hive
,SQLite
, orIsar
instead
๐ ๏ธ Setting Up Shared Preferences
Step 1: Add the Package
In pubspec.yaml
:
dependencies:
shared_preferences: ^2.2.2
Then run:
flutter pub get
๐ฆ Saving Todos to Local Storage
Weโll serialize the list of Todos into JSON strings and store it.
In your todo_provider.dart
:
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
Save Method
Future<void> saveTodos() async {
final prefs = await SharedPreferences.getInstance();
List<String> todoList = _todos.map((todo) => json.encode({
'id': todo.id,
'title': todo.title,
'isDone': todo.isDone,
})).toList();
await prefs.setStringList('todos', todoList);
}
๐ Loading Todos on App Start
Add this method to the provider:
Future<void> loadTodos() async {
final prefs = await SharedPreferences.getInstance();
final List<String>? todoList = prefs.getStringList('todos');
if (todoList != null) {
_todos = todoList.map((todoJson) {
final map = json.decode(todoJson);
return Todo(
id: map['id'],
title: map['title'],
isDone: map['isDone'],
);
}).toList();
notifyListeners();
}
}
Call it in the providerโs constructor or via an init()
method in your main screen:
@override
void initState() {
super.initState();
Provider.of<TodoProvider>(context, listen: false).loadTodos();
}
๐ง Updated Provider Code
Whenever you add, delete, or toggle a todo, call saveTodos()
afterward.
void addTodo(String title) {
// existing logic ...
saveTodos();
}
void toggleTodo(String id) {
// existing logic ...
saveTodos();
}
void deleteTodo(String id) {
// existing logic ...
saveTodos();
}
โ Complete Example
You now have a fully functional app that:
- Adds/removes tasks
- Uses Provider for state
- Saves data locally
- Loads persisted todos on app restart
๐ Next Steps
- ๐ Secure data? Use flutter_secure_storage
- ๐๏ธ Larger data? Use Hive or Isar
- โ Sync across devices? Integrate Firebase
๐ Continue with:
**How to Use Hive for Flutter Offline Storage
๐ฌ Stay in Sync
Get Flutter productivity tips, tutorials, and updates weekly.
Join the FlutterTalk Newsletter โ
โ TL;DR
- Use Shared Preferences for small, local data like settings or short lists
- Serialize data into JSON
- Rehydrate on app startup
- Simple, effective, and beginner-friendly!