Flutter应用重启后如何保存任务数据?基于现有代码如何实现本地持久化
你这个场景存任务列表属于轻量结构化数据,用shared_preferences存序列化后的JSON数据是最简单的落地方式,不需要手动处理文件读写的路径、IO异常等繁琐逻辑,具体修改步骤如下:
1. 新增依赖
在pubspec.yaml的dependencies块添加:
shared_preferences: ^2.2.2
执行flutter pub get安装依赖。
2. 给Task类补充JSON序列化方法
在你现有Task类的基础上补充序列化、反序列化方法即可:
class Task { final String name; bool isDone; Task({required this.name, this.isDone = false}); void toggleDone() { isDone = !isDone; } // 新增:转成可序列化的Map Map<String, dynamic> toJson() { return { 'name': name, 'isDone': isDone, }; } // 新增:从Map解析成Task对象 static Task fromJson(Map<String, dynamic> json) { return Task( name: json['name'], isDone: json['isDone'] ?? false, ); } }
3. 修改TaskData类,增加数据读写逻辑
import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; class TaskData extends ChangeNotifier { List<Task> _tasks = []; // 缓存SharedPreferences实例 late SharedPreferences _prefs; // 存数据用的固定key static const String _tasksKey = 'task_list'; // 标记是否完成初始化,避免空任务场景判断异常 bool isInitialized = false; // 初始化时直接加载本地存储的任务 TaskData() { _initPrefsAndLoadTasks(); } // 初始化sp并加载已存任务 Future<void> _initPrefsAndLoadTasks() async { _prefs = await SharedPreferences.getInstance(); // 读取本地存的JSON字符串 final String? tasksJson = _prefs.getString(_tasksKey); if (tasksJson != null) { // 解析成List<Map>再转成List<Task> final List<dynamic> decodedList = jsonDecode(tasksJson); _tasks = decodedList.map((item) => Task.fromJson(item)).toList(); } else { // 没有存过数据就加载默认示例任务 _tasks = [ Task(name: "Sample task 1"), Task(name: "Sample task 2"), Task(name: "Sample task 3"), ]; } isInitialized = true; notifyListeners(); } // 新增:每次修改任务后同步存到本地 Future<void> _saveTasksToLocal() async { final String encodedJson = jsonEncode(_tasks.map((task) => task.toJson()).toList()); await _prefs.setString(_tasksKey, encodedJson); } UnmodifiableListView<Task> get tasks { return UnmodifiableListView(_tasks); } int get taskCount { return _tasks.length; } void addTask(String newTaskTitle) { final task = Task(name: newTaskTitle); _tasks.add(task); _saveTasksToLocal(); // 修改后同步存本地 notifyListeners(); } void updateTask(Task task) { task.toggleDone(); _saveTasksToLocal(); // 修改后同步存本地 notifyListeners(); } void deleteTask(Task task) { _tasks.remove(task); _saveTasksToLocal(); // 修改后同步存本地 notifyListeners(); } }
4. 优化启动加载逻辑
因为初始化加载数据是异步操作,建议加个加载状态判断,避免刚打开时页面空白:
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => TaskData(), child: MaterialApp( home: Consumer<TaskData>( builder: (context, taskData, child) { // 还没初始化完成时显示加载指示器 if (!taskData.isInitialized) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } return TasksScreen(); }, ), ), ); } }
改完之后所有新增、修改、删除任务的操作都会自动同步到本地存储,重启应用就会自动加载上次的任务数据了。
内容的提问来源于stack exchange,提问作者Bn Minki
相关产品推荐
相关产品推荐

