6

我在 main 中初始化了 box 数据库,如下所示

void main() async {
    WidgetsFlutterBinding.ensureInitialized();
    final appDocumentDirectory = await path_provider.getApplicationDocumentsDirectory();
    Hive.init(appDocumentDirectory.path);
    Hive.registerAdapter(ContactAdapter());
    runApp(MyApp());
}

然后我使用 FutureBuilder 插件在材料应用程序中打开框,如下所示:

  FutureBuilder(
      future: Hive.openBox<Contact>('contacts'),
      builder: (context, snapshot) {
        if(snapshot.connectionState == ConnectionState.done){
          if(snapshot.hasError){
            return Text(snapshot.error.toString() );
          }
          return ContactPage();
        } else {
          return Scaffold();
        }
      }
    ),

在 ContactPage() 里面

我创建了这个:-

  ValueListenableBuilder(
                valueListenable: Hive.box<Contact>('contacts').listenable(),
                builder: (context,Box<Contact> box,_){
                  if(box.values.isEmpty){
                    return Text('data is empty');
                  } else {
                    return ListView.builder(
                      itemCount: box.values.length,
                      itemBuilder: (context,index){
                        var contact = box.getAt(index);
                        return ListTile(
                          title: Text(contact.name),
                          subtitle: Text(contact.age.toString()),
                        );
                      },
                    );
                  }
                },
               )

当我运行应用程序时,出现以下错误

The following HiveError was thrown while handling a gesture:
The box "contacts" is already open and of type Box<Contact>.

当我试图在不打开盒子的情况下使用盒子时,我收到错误意味着盒子没有打开。

我必须使用盒子而不在 ValueListenableBuilder 中打开它吗?但随后我必须在不同的小部件中再次打开同一个框以在其上添加数据。

4

4 回答 4

1

我跳上了这个线程,因为在使用 resocoder 的 Hive 教程时,我很难弄清楚如何处理已弃用的 WatchBoxBuilder,而谷歌搜索将我带到了这里。

这就是我最终使用的:

主要飞镖:

void main() async {
  if (!kIsWeb) { // <-- I put this here so that I could use Hive in Flutter Web
    final dynamic appDocumentDirectory =
        await path_provider.getApplicationDocumentsDirectory();
    Hive.init(appDocumentDirectory.path as String);
  }
  Hive.registerAdapter(ContactAdapter());

  runApp(child: MyApp());
}

然后是 ContactPage() (注意:它与 OP 相同):

Widget _buildListView() {
  return ValueListenableBuilder(
    valueListenable: Hive.box<Contact>('contacts').listenable(),
    builder: (context, Box<Contact> box, _) {
      if (box.values.isEmpty) {
        return Text('data is empty');
      } else {
        return ListView.builder(
          itemCount: box.values.length,
          itemBuilder: (context, index) {
            var contact = box.getAt(index);
            return ListTile(
              title: Text(contact.name),
              subtitle: Text(contact.age.toString()),
            );
          },
        );
      }
    },
  );
}
于 2020-05-10T22:30:45.127 回答
0

它实际上是一个简单的解释:
1。它只发生在你的盒子有一个像
Hive.openBox<User>('users')

2 这样的泛型类型时。所以一旦你在Hive.box('users')没有指定泛型类型的情况下调用这个错误就会发生。

这就是一切


Hive.box<User>('users')每次通话的解决方案:)

于 2021-06-15T21:38:19.397 回答
0

在 main.dart 文件中:

future: Hive.openBox('contacts'),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.hasError) {
            return Text(snapshot.error.toString());
          } else {
            return ContactPage();
          }
        } else {
          return Center(
            child: CircularProgressIndicator(),
          );
        }
      },

在联系页面中:

return WatchBoxBuilder(
box: Hive.box('contacts'),
builder: (context, contactBox) {
  return ListView.builder(
    itemCount: contactBox.length,
    itemBuilder: (context, index) {
      final contact = contactBox.getAt(index) as Contact;
      return ListTile(
        title: Text(contact.name),
        subtitle: Text(contact.number),
        trailing: Row(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            IconButton(
              icon: Icon(Icons.refresh),
              onPressed: () {
                contactBox.putAt(
                  index,
                  Contact('${contact.name}*', contact.number),
                );
              },
            ),
            IconButton(
              icon: Icon(Icons.delete),
              onPressed: () {
                contactBox.deleteAt(index);
              },
            ),
          ],
        ),
      );
    },
  );
},

);

以后打电话开箱就好了。。

于 2020-04-10T23:26:27.177 回答
0

这可能是因为你试图打开里面的盒子FutureBuilder。如果它试图重建自己,它会尝试打开已经打开的盒子。您可以在注册适配器后尝试打开该框,例如:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final appDocumentDirectory = await path_provider.getApplicationDocumentsDirectory();
  Hive.init(appDocumentDirectory.path);
  Hive.registerAdapter(ContactAdapter());
  await Hive.openBox<Contact>('contacts');
  runApp(MyApp());
}

FutureBuilder不仅仅是返回ContactPage

于 2020-02-17T07:34:43.980 回答