我在尝试访问flutter中的配置单元数据库时遇到此错误,因为“contacts”框已经打开,并且类型为box< contact>

guz6ccqo  于 2021-06-25  发布在  Hive
关注(0)|答案(3)|浏览(354)

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

void main() async {

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

然后我使用futurebuilder插件打开material应用程序中的box,如下所示

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();
      }
    }
  ),

和内部联系人页()
我创造this:-

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中使用box而不打开它吗?但是我必须在不同的小部件中再次打开同一个框来添加数据

xriantvc

xriantvc1#

可能是因为你想打开里面的盒子 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

pgx2nnw8

pgx2nnw82#

我跳上这个线程是因为在使用resocoder的hive教程时,我很难弄清楚如何处理弃用的watchboxbuilder,一个google搜索把我带到了这里。
这就是我最终使用的:
main.dart:

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()),
            );
          },
        );
      }
    },
  );
}
jutyujz0

jutyujz03#

在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(),
          );
        }
      },

在contactpage中:

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);
              },
            ),
          ],
        ),
      );
    },
  );
},

);
以后打电话时可以打开盒子。。

相关问题