Flutter中如何将JSON解码为Map<DateTime, List<Task>>
解决JSON解码为
LinkedHashMap<DateTime, List<Task>>的问题 核心问题梳理
你的解码逻辑存在多处错误:Task类的枚举转换缺失、fromJson工厂方法调用错误、TaskList.fromJson的遍历逻辑错误,以及读取SharedPreferences时未正确调用自定义解码方法。以下是分步修正方案:
1. 修复Task类的fromJson方法与枚举转换
原代码直接将字符串赋值给PriorityItem类型会导致类型错误,需要添加字符串转枚举的逻辑,同时修正构造函数调用方式:
class Task { late int taskId; late bool isCompleted; late String text; late PriorityItem priority; // 规范构造函数参数 Task({ required this.taskId, required this.isCompleted, required this.text, required this.priority, }); Map<String, dynamic> toJson() => { "id": taskId, "isCompleted": isCompleted, "text": text, "priority": priority.toString(), }; factory Task.fromJson(Map<String, dynamic> json) { // 字符串转PriorityItem枚举 PriorityItem priority; switch (json["priority"]) { case "PriorityItem.low": priority = PriorityItem.low; break; case "PriorityItem.medium": priority = PriorityItem.medium; break; case "PriorityItem.high": priority = PriorityItem.high; break; default: priority = PriorityItem.low; // 设置默认值避免崩溃 } return Task( taskId: json["id"], isCompleted: json["isCompleted"], text: json["text"], priority: priority, ); } } enum PriorityItem { low, medium, high, }
2. 修复TaskList类的fromJson方法
原代码存在初始化错误、遍历逻辑错误(错误使用json[value]),以及Task对象转换错误,修正如下:
class TaskList { static LinkedHashMap<DateTime, List<Task>> weeklyTaskMap = LinkedHashMap<DateTime, List<Task>>(); static LinkedHashMap<DateTime, List<Task>> taskMap = LinkedHashMap<DateTime, List<Task>>(); // 补充原代码缺失的taskMap static Map<String, dynamic> toJson(LinkedHashMap<DateTime, List<Task>> taskMap) { Map<String, dynamic> myMap = {}; taskMap.forEach((key, value) { myMap[key.toIso8601String()] = List<dynamic>.from(value.map((x) => x.toJson())); }); return myMap; } static LinkedHashMap<DateTime, List<Task>> fromJson(Map<String, dynamic> json) { // 正确初始化LinkedHashMap,避免强制类型转换错误 LinkedHashMap<DateTime, List<Task>> myMap = LinkedHashMap<DateTime, List<Task>>(); json.forEach((key, value) { // 将JSON中的任务列表转换为List<Task> List<Task> tasks = List<Task>.from( (value as List<dynamic>).map((taskJson) => Task.fromJson(taskJson as Map<String, dynamic>)), ); myMap[DateTime.parse(key)] = tasks; }); return myMap; } }
3. 修复getMapsFromPrefs的解码逻辑
原代码中weeklyMap直接使用jsonDecode,未调用TaskList.fromJson导致类型不匹配,修正如下:
void getMapsFromPrefs() async { SharedPreferences getMaps = await _prefs; // 先解码得到Map<String, dynamic>,再传入自定义fromJson转换 Map<String, dynamic> dailyJson = jsonDecode(getMaps.getString('daily')!); Map<String, dynamic> weeklyJson = jsonDecode(getMaps.getString('weekly')!); TaskList.taskMap = TaskList.fromJson(dailyJson); TaskList.weeklyTaskMap = TaskList.fromJson(weeklyJson); } void saveMapsToPrefs() async { SharedPreferences getMaps = await _prefs; getMaps.clear(); var dailyTasksJson = json.encode(TaskList.toJson(TaskList.taskMap)); var weeklyTasksJson = json.encode(TaskList.toJson(TaskList.weeklyTaskMap)); getMaps.setString('daily', dailyTasksJson); getMaps.setString('weekly', weeklyTasksJson); print("saved ${getMaps.getString('daily')}"); }
关键修正点总结
- 枚举转换:JSON不支持枚举直接序列化/反序列化,必须手动将字符串枚举值转换为
PriorityItem类型。 - fromJson逻辑:遍历JSON时直接使用
value(对应日期键下的任务列表),而非错误的json[value];正确初始化LinkedHashMap,避免强制类型转换导致的错误。 - 解码流程:从SharedPreferences读取的JSON字符串,必须先通过
jsonDecode得到Map<String, dynamic>,再传入TaskList.fromJson转换为目标类型,不能直接赋值。
内容的提问来源于stack exchange,提问作者deeppurple
相关产品推荐
相关产品推荐

