【问题标题】:How to write custom class object in hive object?如何在 hive 对象中编写自定义类对象?
【发布时间】:2020-01-13 13:01:55
【问题描述】:

在颤振中使用 hive 时,我在 hive 对象中使用了我的自定义类对象 Profile profile

所以,最初,我将自定义类对象(Profile profile)设置为null,同时添加到 Hive 框中。

以下是我的 Hive 课程:

import 'dart:convert';
import 'package:hive/hive.dart';
import 'package:lpa_exam/src/model/listofexams.dart';
import 'package:lpa_exam/src/model/profile.dart';
part 'hiveprofile.g.dart';

@HiveType()
class PersonModel extends HiveObject{
  @HiveField(0)
  String language;

  @HiveField(1)
  String examName;

  @HiveField(2)
  int examId;

  @HiveField(3)
  Profile profile;

  @HiveField(4)
  ListExam listexam;

  @override
  String toString() {
    return jsonEncode({
      'language': this.language,
      'examName': this.examName,
      'examId': this.examId,
      'profile': this.profile,
      'listexam': this.listexam
    });
  }

  PersonModel(
      this.language, this.examName, this.examId, this.profile, this.listexam);
}

档案类供参考:

class Profile {
  String name='';
  String lang='';
  String emailId='';
  String mobileNumber='';
  String state='';
  String city='';
  String district='';
  String pinCode='';
  String profilePic='';
  Profile(
      this.name,
      this.lang,
      this.emailId,
      this.mobileNumber,
      this.district,
      this.state,
      this.city,
      this.pinCode,this.profilePic);

  Profile.fromJson(Map<String, dynamic> json) {
    // print('fromjson:$json');
    if (json != null) {
      name = json['name'];
      lang = json['language'];
      emailId = json['emailId'];
      mobileNumber = json['mobileNumber'];
      district = json['district'];
      state = json['state'];
      city = json['city'];
      pinCode = json['pinCode'];
      profilePic=json['profilePic'];
    } else {
      print('in else profile from json');
      // name = '';
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['name'] = this.name;
    data['language'] = this.lang;
    data['emailId'] = this.emailId;
    data['mobileNumber'] = this.mobileNumber;
    data['district'] = this.district;
    data['state'] = this.state;
    data['city'] = this.city;
    data['pinCode'] = this.pinCode;
    data['profilePic']=this.profilePic;
    return data;
  }
}

当我尝试像这样添加添加的对象时发生错误

item.add(PersonModel(label, null, null, Profile(), ListExam())); // label='English'

以下是发生的错误:

[VERBOSE-2:ui_dart_state.cc(157)] 未处理的异常:HiveError:无法写入,未知类型:配置文件。您忘记注册适配器了吗?

现在,有人可以指出我在这里做错了什么吗?

【问题讨论】:

    标签: flutter


    【解决方案1】:

    Hive 插件默认支持原语、列表和地图。要将它用于您自己的 Dart 对象,您需要生成一个 TypeAdapter。

    您需要为您拥有的每个对象创建一个 TypeAdapter。所以你需要为 Profile 类应用与 PersonModel

    相同的东西
    part 'profile.g.dart';
    
    @HiveType()
    class Profile {
      @HiveField(0)
      String name;
      @HiveField(1)
      String lang;
      @HiveField(2)
      String emailId;
      @HiveField(3)
      String mobileNumber;
      @HiveField(4)
      String state;
      @HiveField(5)
      String city;
      @HiveField(6)
      String district;
      @HiveField(7)
      String pinCode;
      @HiveField(8)
      String profilePic;
    
      Profile(
          this.name,
          this.lang,
          this.emailId,
          this.mobileNumber,
          this.district,
          this.state,
          this.city,
          this.pinCode,this.profilePic);      
    
    
      Profile.fromJson(Map<String, dynamic> json) {
        // print('fromjson:$json');
        if (json != null) {
          name = json['name'];
          lang = json['language'];
          emailId = json['emailId'];
          mobileNumber = json['mobileNumber'];
          district = json['district'];
          state = json['state'];
          city = json['city'];
          pinCode = json['pinCode'];
          profilePic=json['profilePic'];
        } else {
          print('in else profile from json');
          // name = '';
        }
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['name'] = this.name;
        data['language'] = this.lang;
        data['emailId'] = this.emailId;
        data['mobileNumber'] = this.mobileNumber;
        data['district'] = this.district;
        data['state'] = this.state;
        data['city'] = this.city;
        data['pinCode'] = this.pinCode;
        data['profilePic']=this.profilePic;
        return data;
     }
    
    }
    

    如果您使用的是最新的 hive 版本,您还需要为您的 HiveType 提供一个类型 id,例如

    @HiveType(typeId: 0)
    

    我发现您还有另一个名为 ListExam 的自定义类。您还需要为该课程做同样的事情

    【讨论】:

      【解决方案2】:

      您可以在main.dartmain.g.dart下方复制粘贴运行完整代码
      对于演示,我备注listexam
      您需要 registerAdapter(ProfileAdapter())
      创建 class ProfileAdapter extends TypeAdapter&lt;Profile&gt; 见下面的完整代码
      代码sn-p

      Hive
          ..init(dir.path)
          ..registerAdapter(PersonModelAdapter())
          ..registerAdapter(ProfileAdapter());
      
      
        var box = await Hive.openBox('testBox');
      
        var personModel = PersonModel(
            language: "en",
            examName: "abc",
            examId: 123,
            profile: Profile(name: "test", emailId: "a@b.com"));
      
        await box.put('test', personModel);
      
        print(box.get('test'));
      

      输出

      I/flutter (10795): {"language":"en","examName":"abc","examId":123,"profile":{"name":"test","language":null,"emailId":"a@b.com","mobileNumber":null,"district":null,"state":null,"city":null,"pinCode":null,"profilePic":null}}
      

      main.dart

      import 'dart:io';
      import 'dart:convert';
      import 'package:flutter/material.dart';
      import 'package:hive/hive.dart';
      import 'package:path_provider/path_provider.dart';
      
      part 'main.g.dart';
      
      @HiveType(typeId: 1)
      class PersonModel extends HiveObject {
        @HiveField(0)
        String language;
      
        @HiveField(1)
        String examName;
      
        @HiveField(2)
        int examId;
      
        @HiveField(3)
        Profile profile;
      
        /*@HiveField(4)
        ListExam listexam;*/
      
        @override
        String toString() {
          return jsonEncode({
            'language': this.language,
            'examName': this.examName,
            'examId': this.examId,
            'profile': this.profile,
            //'listexam': this.listexam
          });
        }
      
        PersonModel(
            {this.language,
            this.examName,
            this.examId,
            this.profile} /*, this.listexam*/);
      }
      
      @HiveType(typeId: 2)
      class Profile extends HiveObject {
        String name = '';
        String lang = '';
        String emailId = '';
        String mobileNumber = '';
        String state = '';
        String city = '';
        String district = '';
        String pinCode = '';
        String profilePic = '';
      
        Profile(
            {this.name,
            this.lang,
            this.emailId,
            this.mobileNumber,
            this.district,
            this.state,
            this.city,
            this.pinCode,
            this.profilePic});
      
        Profile.fromJson(Map<String, dynamic> json) {
          // print('fromjson:$json');
          if (json != null) {
            name = json['name'];
            lang = json['language'];
            emailId = json['emailId'];
            mobileNumber = json['mobileNumber'];
            district = json['district'];
            state = json['state'];
            city = json['city'];
            pinCode = json['pinCode'];
            profilePic = json['profilePic'];
          } else {
            print('in else profile from json');
            // name = '';
          }
        }
      
        Map<String, dynamic> toJson() {
          final Map<String, dynamic> data = new Map<String, dynamic>();
          data['name'] = this.name;
          data['language'] = this.lang;
          data['emailId'] = this.emailId;
          data['mobileNumber'] = this.mobileNumber;
          data['district'] = this.district;
          data['state'] = this.state;
          data['city'] = this.city;
          data['pinCode'] = this.pinCode;
          data['profilePic'] = this.profilePic;
          return data;
        }
      }
      
      void main() async {
        WidgetsFlutterBinding.ensureInitialized();
        var dir = await getApplicationDocumentsDirectory();
        Hive
          ..init(dir.path)
          ..registerAdapter(PersonModelAdapter())
          ..registerAdapter(ProfileAdapter());
      
        var box = await Hive.openBox('testBox');
      
        var personModel = PersonModel(
            language: "en",
            examName: "abc",
            examId: 123,
            profile: Profile(name: "test", emailId: "a@b.com"));
      
        await box.put('test', personModel);
      
        print(box.get('test'));
      }
      

      main.g.dart

      part of 'main.dart';
      
      // **************************************************************************
      // TypeAdapterGenerator
      // **************************************************************************
      
      class PersonModelAdapter extends TypeAdapter<PersonModel> {
        @override
        final typeId = 1;
      
        @override
        PersonModel read(BinaryReader reader) {
          var numOfFields = reader.readByte();
          var fields = <int, dynamic>{
            for (var i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
          };
          return PersonModel()
            ..language = fields[0] as String
            ..examName = fields[1] as String
            ..examId = fields[2] as int
            ..profile = fields[3] as Profile;
        }
      
        @override
        void write(BinaryWriter writer, PersonModel obj) {
          writer
            ..writeByte(3)
            ..writeByte(0)
            ..write(obj.language)
            ..writeByte(1)
            ..write(obj.examName)
            ..writeByte(2)
            ..write(obj.examId)
            ..writeByte(3)
            ..write(obj.profile);
        }
      }
      
      class ProfileAdapter extends TypeAdapter<Profile> {
        @override
        final typeId = 2;
      
        @override
        Profile read(BinaryReader reader) {
          var numOfFields = reader.readByte();
          var fields = <int, dynamic>{
            for (var i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
          };
          return Profile()
            ..name = fields[0] as String
            ..lang = fields[1] as String
            ..emailId = fields[2] as String
            ..mobileNumber = fields[3] as String
            ..district = fields[4] as String
            ..state = fields[5] as String
            ..city = fields[6] as String
            ..pinCode = fields[7] as String
            ..profilePic = fields[8] as String;
        }
      
        @override
        void write(BinaryWriter writer, Profile obj) {
          writer
            ..writeByte(3)
            ..writeByte(0)
            ..write(obj.name)
            ..writeByte(1)
            ..write(obj.lang)
            ..writeByte(2)
            ..write(obj.emailId)
            ..writeByte(3)
            ..write(obj.mobileNumber)
            ..writeByte(4)
            ..write(obj.district)
            ..writeByte(5)
            ..write(obj.state)
            ..writeByte(6)
            ..write(obj.city)
            ..writeByte(7)
            ..write(obj.pinCode)
            ..writeByte(8)
            ..write(obj.profilePic);
        }
      }
      

      【讨论】:

      • 嗨,我需要在 hive 中存储 firestore 对象列表。如何为快照列表创建类型适配器?
      • 有没有办法在hive中使用json注解?我的意思是带有@JsonSerializable() 和@HiveType() @chunhunghan 的类
      【解决方案3】:

      希望对您有所帮助!

      @HiveType(typeId: 0)
      class TradingJournalLocal extends HiveObject {
        @HiveField(0)
        late String orderType;
      
        @HiveField(1)
        late String title; 
      
        @HiveField(2)
        late List<Emotion> emotions; 
      } 
      
      @HiveType(typeId: 1)
      class Emotion extends HiveObject {
        @HiveField(0)
        late int id;
      
        @HiveField(1)
        late String emoji; 
      
        Emotion({
          required this.id,
          required this.emoji,
        });
      
        factory Emotion.fromJson(Map<String, dynamic> json) => Emotion(
              id: json['id'],
              emoji: json['emoji'],
            ); 
      }
      

      【讨论】:

        猜你喜欢
        • 2014-03-19
        • 1970-01-01
        • 2019-06-12
        • 2020-11-21
        • 2018-03-23
        • 1970-01-01
        • 1970-01-01
        • 2015-11-22
        • 2014-05-28
        相关资源
        最近更新 更多