如何为基于Provider的Flutter应用添加持久化存储逻辑?
为Provider状态添加自定义对象列表的持久化实现方案
步骤1:添加持久化依赖
在pubspec.yaml中添加shared_preferences依赖,用于存储序列化后的JSON数据:
dependencies: flutter: sdk: flutter provider: ^6.0.5 shared_preferences: ^2.2.2
执行flutter pub get完成依赖安装。
步骤2:让自定义类支持序列化
修改MyData类,添加JSON转换方法,处理DateTime的字符串转换(因为SharedPreferences无法直接存储DateTime类型):
class MyData { final DateTime time; final int value; MyData(this.time, this.value); // 转换为JSON格式 Map<String, dynamic> toJson() { return { 'time': time.toIso8601String(), 'value': value, }; } // 从JSON解析为MyData对象 factory MyData.fromJson(Map<String, dynamic> json) { return MyData( DateTime.parse(json['time']), json['value'], ); } }
步骤3:修改状态类,加入持久化逻辑
将原State类重命名为DataState(避免与Flutter内置State冲突),添加加载/保存数据的异步方法,并在数据变更后自动触发保存:
import 'package:shared_preferences/shared_preferences.dart'; class DataState with ChangeNotifier { late List<MyData> _dataset = []; List<MyData> get dataset => _dataset; DataState() { // 初始化时加载本地存储的数据 _loadData(); } // 从本地加载数据 Future<void> _loadData() async { final prefs = await SharedPreferences.getInstance(); final jsonString = prefs.getString('dataset'); if (jsonString != null) { final List<dynamic> jsonList = jsonDecode(jsonString) as List; _dataset = jsonList.map((json) => MyData.fromJson(json)).toList(); notifyListeners(); } } // 将数据保存到本地 Future<void> _saveData() async { final prefs = await SharedPreferences.getInstance(); final List<Map<String, dynamic>> jsonList = _dataset.map((data) => data.toJson()).toList(); await prefs.setString('dataset', jsonEncode(jsonList)); } void addData(DateTime time, int value) { MyData datapoint = MyData(time, value); _dataset.add(datapoint); notifyListeners(); _saveData(); } void clearData() { _dataset = []; notifyListeners(); _saveData(); } }
步骤4:更新Provider注册与UI调用
- 修改
main函数中的Provider注册:
void main() { runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => DataState()), ], child: const MyApp(), ), ); }
- 更新UI中对状态类的引用:
// MyHomePage中的按钮点击事件 IconButton( onPressed: () => context.read<DataState>().addData(DateTime.now(), 100), icon: const Icon(Icons.add)), IconButton( onPressed: () => context.read<DataState>().clearData(), icon: const Icon(Icons.remove))
// Count组件中的状态监听 '${context.watch<DataState>().dataset.length}',
注意事项
SharedPreferences适合存储轻量数据,若数据集较大,建议改用Hive或sqflite等本地数据库方案- 确保所有数据变更操作后都调用
_saveData,避免数据丢失 - 采用ISO8601格式存储
DateTime,保证跨平台解析的兼容性
内容的提问来源于stack exchange,提问作者Hultan
相关产品推荐
相关产品推荐

