Hive提示未知类型TimeOfDay,已注册适配器仍无法写入数据如何解决?
问题原因
你已注册的是自定义TasksModel的适配器,但TimeOfDay属于Flutter框架自带类型,Hive默认仅支持String、int、bool、List、Map、DateTime等基础类型,本身不识别TimeOfDay,也不会自动为框架/第三方类型生成适配器。且Hive不会递归处理自定义模型内的嵌套类型,所有非默认支持的字段类型都需要单独注册对应适配器,因此序列化时会触发未知类型报错。
解决方案
方案1:自定义TimeOfDay适配器(推荐)
- 新增
TimeOfDayAdapter类
import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; class TimeOfDayAdapter extends TypeAdapter<TimeOfDay> { @override // 确保typeId全局唯一,不要和你已有的适配器typeId重复 final int typeId = 1; @override TimeOfDay read(BinaryReader reader) { final hour = reader.readInt(); final minute = reader.readInt(); return TimeOfDay(hour: hour, minute: minute); } @override void write(BinaryWriter writer, TimeOfDay obj) { writer.writeInt(obj.hour); writer.writeInt(obj.minute); } }
- 在Hive初始化阶段、打开box之前注册该适配器
Hive.registerAdapter(TasksModelAdapter()); // 新增TimeOfDay适配器注册 Hive.registerAdapter(TimeOfDayAdapter()); // 再执行打开box操作 await Hive.openBox('todoTasks');
方案2:转换为Hive支持的类型存储
如果不想额外写适配器,可把TimeOfDay转换为int/string类型存储,存取时自动转换:
修改task_model.dart内容:
import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; part 'task_model.g.dart'; @HiveType(typeId = 0) class TasksModel{ @HiveField(0) String taskDetails; @HiveField(1) bool isChecked = false; @HiveField(2) String priority; // 替换原来的TimeOfDay类型,存储为总分钟数,例13:30对应13*60+30=810 @HiveField(3) int timeMinutes; @HiveField(4) DateTime date; // 内置getter直接获取TimeOfDay格式,不用业务层额外转换 TimeOfDay get time => TimeOfDay(hour: timeMinutes ~/ 60, minute: timeMinutes % 60); TasksModel({@required this.taskDetails, @required this.isChecked, @required this.priority, @required TimeOfDay time, @required this.date}) : timeMinutes = time.hour * 60 + time.minute; void toggle(){ isChecked = !isChecked; } }
修改完成后重新执行生成命令更新.g.dart文件即可:flutter packages pub run build_runner build
内容的提问来源于stack exchange,提问作者Vortenzie
相关产品推荐
相关产品推荐

