You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用SharedPreferences保存Map类型的Provider数据?

解决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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 12:37:57