如何使用SharedPreferences保存Map类型的Provider数据?
嗨,我来帮你搞定这个问题!SharedPreferences本身确实没有直接存储Map的API,但咱们可以借助JSON序列化的方式,把整个Map转换成字符串来存储,读取时再转成Map,这样就能一次性处理你的整个selectedTimes数据啦。
步骤1:导入JSON序列化工具包
首先要导入dart:convert,因为我们需要用到jsonEncode和jsonDecode方法:
import 'dart:convert';
步骤2:修改SharedPreferences操作代码
直接修改你现有的_initPref和_changedTime方法,把Map转成JSON字符串存储,读取时再解析回来:
读取数据的_initPref方法:
Future<int> _initPref() async { prefs = await SharedPreferences.getInstance(); // 读取存储的JSON字符串 var timeDataString = prefs.getString('timeData'); if (timeDataString != null) { // 将JSON字符串解析为Map,覆盖原有的selectedTimes settingDataHandler.selectedTimes = Map<String, dynamic>.from( jsonDecode(timeDataString) as Map<String, dynamic> ); } pomodoroHandler.pomodoroTime = settingDataHandler.selectedTimes["Pomodoro Setting"]; pomodoroHandler.time = pomodoroHandler.pomodoroTime * 60; return 0; }
保存数据的_changedTime方法:
Future<void> _changedTime() async { prefs = await SharedPreferences.getInstance(); // 将整个Map转换成JSON字符串 var timeDataString = jsonEncode(settingDataHandler.selectedTimes); // 存储字符串 await prefs.setString('timeData', timeDataString); }
进阶优化:把数据操作封装到Provider里
为了让代码更整洁、职责更清晰,你可以把保存和读取的逻辑封装到SettingDataHandler类中:
class SettingDataHandler extends ChangeNotifier { Map<String, dynamic> selectedTimes = { "Pomodoro Setting": 15, "Rest Time Setting": 5, "Long Rest Time Setting": 15, "Term of Resting Time Setting": 5 }; // 从SharedPreferences加载数据 Future<void> loadFromPrefs(SharedPreferences prefs) async { var timeDataString = prefs.getString('timeData'); if (timeDataString != null) { selectedTimes = Map<String, dynamic>.from( jsonDecode(timeDataString) as Map<String, dynamic> ); notifyListeners(); } } // 保存数据到SharedPreferences Future<void> saveToPrefs(SharedPreferences prefs) async { var timeDataString = jsonEncode(selectedTimes); await prefs.setString('timeData', timeDataString); } setTime(String typeOfSetting, int changeValue) { selectedTimes.update(typeOfSetting, (value) => changeValue); notifyListeners(); } }
之后调用的时候就更简洁了:
Future<int> _initPref() async { prefs = await SharedPreferences.getInstance(); await settingDataHandler.loadFromPrefs(prefs); pomodoroHandler.pomodoroTime = settingDataHandler.selectedTimes["Pomodoro Setting"]; pomodoroHandler.time = pomodoroHandler.pomodoroTime * 60; return 0; } Future<void> _changedTime() async { prefs = await SharedPreferences.getInstance(); await settingDataHandler.saveToPrefs(prefs); }
注意事项
- 你的
selectedTimes里的键值类型(String和int)都是JSON支持的类型,所以序列化不会有问题;如果之后要添加其他复杂类型,可能需要额外处理序列化逻辑。 - 一定要确保导入了
dart:convert包,否则jsonEncode和jsonDecode会报错。
这样一来,你就能一次性保存和读取整个Map类型的Provider数据啦!
内容的提问来源于stack exchange,提问作者Nate Yeum
相关产品推荐
相关产品推荐

