如何为 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 复制整个源代码,添加 HiveTypeHiveField 装饰器并从中生成适配器或两个 - 创建将从 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.