如何为 XFile 创建 Hive 适配器 class
How to create Hive adapter for XFile class
我正在尝试存储具有 XFile
的可变存储列表的自定义对象;来自名为 image_picker
版本 0.8.4+3
的包的跨平台图像表示。写入时出现错误,说我缺少 XFile
的适配器,这是可以理解的,但我很难决定如何为外部源文件 class.
声明此类适配器
这是我的 Receipt
class,其中包含一些 XFile
的列表。
注意:我已经从代码片段中删除了无意义的变量。
@HiveType(typeId: 0)
class Receipt extends HiveObject with EquatableMixin {
Receipt({
List<XFile>? files,
}) {
this.files = files ?? <XFile>[];
}
@HiveField(6)
late final List<XFile> files;
@override
List<Object?> get props => [
files,
];
}
现在我在考虑两种可能的解决方案;一 - 从 XFile
复制整个源代码,添加 HiveType
和 HiveField
装饰器并从中生成适配器或两个 - 创建将从 XFile 扩展的 class 并添加装饰器之类的东西这个:
@HiveType(typeId: 1)
class XFileAdapter extends XFile with HiveObjectMixin {
// access fields and add decorators here
}
但我不知道如何在不覆盖每个字段的情况下向这些字段添加装饰器。即使我知道该怎么做,事实证明 XFile
没有我可以添加 Hive 装饰器的自己的变量,它只是获取参数并将它们传递给 XFileBase
class 因为它进一步决定如何处理它们。
有人问过非常相似的问题 in this thread 但唯一的答案是建议从头开始创建新的 class 来模仿源代码 class 这不是我的问题的解决方案。
我认为按照您的建议创建一个新的 MyXFile
class 可能是可行的方法。但是正如您所说,您将需要覆盖要保留在配置单元中的属性。此代码似乎按预期工作:
代码
import 'dart:typed_data';
import 'package:image_picker/image_picker.dart';
import 'package:hive_flutter/adapters.dart';
part 'my_xfile.g.dart';
@HiveType(typeId: 1)
class MyXFile extends XFile {
@override
@HiveField(1)
final String path;
@override
@HiveField(2)
final String? mimeType;
@HiveField(3)
final String? _name;
/// The base implementation of `XFileBase.name` throws an
/// [UnimplementedError] so we are overriding it to return a known
/// [_name] value.
@override
String get name {
if (_name != null) {
return _name!;
}
return super.name;
}
@HiveField(4)
final int? _length;
/// The base implementation of `XFileBase.length()` throws an
/// [UnimplementedError] so we are overriding it to return a known
/// [_length] value.
@override
Future<int> length() {
return _length != null ? Future.value(_length!) : super.length();
}
@HiveField(5)
final Uint8List? bytes;
@HiveField(6)
final DateTime? _lastModified;
/// The base implementation of `XFileBase.lastModified()` throws an
/// [UnimplementedError] so we are overriding it to return a known
/// [_lastModified] value.
@override
Future<DateTime> lastModified() {
return _lastModified != null
? Future.value(_lastModified!)
: super.lastModified();
}
MyXFile(
this.path, {
this.mimeType,
String? name,
int? length,
this.bytes,
DateTime? lastModified,
}) : _name = name,
_length = length,
_lastModified = lastModified,
super(
path,
mimeType: mimeType,
name: name,
length: length,
bytes: bytes,
lastModified: lastModified,
);
}
通过使用它我已经能够保存和检索我的对象 MyXFile
并且因为它正在扩展 XFile
你应该能够以相同的方式使用它。
那么您的 Receipt
class 中不需要 List<XFile>? files
,您需要 List<MyXFile>? files
.
我正在尝试存储具有 XFile
的可变存储列表的自定义对象;来自名为 image_picker
版本 0.8.4+3
的包的跨平台图像表示。写入时出现错误,说我缺少 XFile
的适配器,这是可以理解的,但我很难决定如何为外部源文件 class.
这是我的 Receipt
class,其中包含一些 XFile
的列表。
注意:我已经从代码片段中删除了无意义的变量。
@HiveType(typeId: 0)
class Receipt extends HiveObject with EquatableMixin {
Receipt({
List<XFile>? files,
}) {
this.files = files ?? <XFile>[];
}
@HiveField(6)
late final List<XFile> files;
@override
List<Object?> get props => [
files,
];
}
现在我在考虑两种可能的解决方案;一 - 从 XFile
复制整个源代码,添加 HiveType
和 HiveField
装饰器并从中生成适配器或两个 - 创建将从 XFile 扩展的 class 并添加装饰器之类的东西这个:
@HiveType(typeId: 1)
class XFileAdapter extends XFile with HiveObjectMixin {
// access fields and add decorators here
}
但我不知道如何在不覆盖每个字段的情况下向这些字段添加装饰器。即使我知道该怎么做,事实证明 XFile
没有我可以添加 Hive 装饰器的自己的变量,它只是获取参数并将它们传递给 XFileBase
class 因为它进一步决定如何处理它们。
有人问过非常相似的问题 in this thread 但唯一的答案是建议从头开始创建新的 class 来模仿源代码 class 这不是我的问题的解决方案。
我认为按照您的建议创建一个新的 MyXFile
class 可能是可行的方法。但是正如您所说,您将需要覆盖要保留在配置单元中的属性。此代码似乎按预期工作:
代码
import 'dart:typed_data';
import 'package:image_picker/image_picker.dart';
import 'package:hive_flutter/adapters.dart';
part 'my_xfile.g.dart';
@HiveType(typeId: 1)
class MyXFile extends XFile {
@override
@HiveField(1)
final String path;
@override
@HiveField(2)
final String? mimeType;
@HiveField(3)
final String? _name;
/// The base implementation of `XFileBase.name` throws an
/// [UnimplementedError] so we are overriding it to return a known
/// [_name] value.
@override
String get name {
if (_name != null) {
return _name!;
}
return super.name;
}
@HiveField(4)
final int? _length;
/// The base implementation of `XFileBase.length()` throws an
/// [UnimplementedError] so we are overriding it to return a known
/// [_length] value.
@override
Future<int> length() {
return _length != null ? Future.value(_length!) : super.length();
}
@HiveField(5)
final Uint8List? bytes;
@HiveField(6)
final DateTime? _lastModified;
/// The base implementation of `XFileBase.lastModified()` throws an
/// [UnimplementedError] so we are overriding it to return a known
/// [_lastModified] value.
@override
Future<DateTime> lastModified() {
return _lastModified != null
? Future.value(_lastModified!)
: super.lastModified();
}
MyXFile(
this.path, {
this.mimeType,
String? name,
int? length,
this.bytes,
DateTime? lastModified,
}) : _name = name,
_length = length,
_lastModified = lastModified,
super(
path,
mimeType: mimeType,
name: name,
length: length,
bytes: bytes,
lastModified: lastModified,
);
}
通过使用它我已经能够保存和检索我的对象 MyXFile
并且因为它正在扩展 XFile
你应该能够以相同的方式使用它。
那么您的 Receipt
class 中不需要 List<XFile>? files
,您需要 List<MyXFile>? files
.