问题
I initialized box database in main as follow
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final appDocumentDirectory = await path_provider.getApplicationDocumentsDirectory();
Hive.init(appDocumentDirectory.path);
Hive.registerAdapter(ContactAdapter());
runApp(MyApp());
}
then I open box in the material app by using FutureBuilder plugin as follow
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();
}
}
),
and inside ContactPage()
I create 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()),
);
},
);
}
},
)
when I run the application I get the following error
The following HiveError was thrown while handling a gesture:
The box "contacts" is already open and of type Box<Contact>.
and when I tried to use the box without opening it, i got error mean the box is not open
do I have to use box without opening it inside ValueListenableBuilder ? but then i have to open same box again in the different widget to add data on it
回答1:
In main.dart file :
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(),
);
}
},
In 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);
},
),
],
),
);
},
);
},
);
It's OK to open the box in future call..
回答2:
It is probably because you are trying to open the box inside FutureBuilder. If somehow it tries to rebuild itself, it will try to open the box which is already opened. Can you try to open the box after you register the adapter like:
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());
}
And instead of FutureBuilder just return ContactPage
回答3:
I'm jumping on this thread because I had a hard time trying to figure out how to deal with the deprecated WatchBoxBuilder while using the resocoder's Hive tutorial, and a google search led me here.
This is what I ended up using:
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());
}
and then ContactPage() (note: it's the same as OP's):
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()),
);
},
);
}
},
);
}
来源:https://stackoverflow.com/questions/60257233/i-got-this-error-when-i-tried-to-access-hive-database-in-flutter-the-box-contac