如何解决 Box not Found 错误 Hive Flutter
Posted
技术标签:
【中文标题】如何解决 Box not Found 错误 Hive Flutter【英文标题】:How to solve the Box not Found error Hive Flutter 【发布时间】:2021-03-04 18:51:43 【问题描述】:我有一个主屏幕,我在其中创建了一个 4 导航屏幕,所以当用户输入登录 ID 和密码时,它会调用主屏幕。但是当用户第一次导航到主屏幕时,它显示 Box 未初始化,但是当我点击底部导航栏时,它显示了列表,但我想显示列表,即使用户先登录。
这是我的错误:
这是用户登录时的主屏幕代码:
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
import 'package:secret_keeper/Database/Hive/BankModel.dart';
import 'package:secret_keeper/Database/Hive/CardModel.dart';
import 'package:secret_keeper/Database/Hive/NotesModel.dart';
import 'package:secret_keeper/Database/Hive/PasswordModel.dart';
import 'package:secret_keeper/screens/home_screen/banks/BanksNavigation.dart';
import 'package:secret_keeper/screens/home_screen/cards/CardsNavigation.dart';
import 'package:secret_keeper/screens/home_screen/notes/NotesNavigation.dart';
import 'package:secret_keeper/screens/home_screen/passwords/PasswordsNavigation.dart';
import 'package:secret_keeper/screens/input_screen/bank_input/BankInput.dart';
import 'package:secret_keeper/screens/input_screen/card_input/CardInput.dart';
import 'package:secret_keeper/screens/input_screen/note_input/NoteInput.dart';
import 'package:secret_keeper/screens/input_screen/password_input/PasswordInput.dart';
Box passwordBox, cardBox, bankBox, notesBox;
class Home extends StatefulWidget
@override
_HomeState createState() => _HomeState();
class _HomeState extends State<Home>
//Properties
int currentTab = 0;
final List<Widget> screens = [
PasswordsNavigation(),
CardsNavigation(),
BanksNavigation(),
NotesNavigation(),
];
@override
void initState()
// TODO: implement initState
super.initState();
Hive.registerAdapter(PasswordModelAdapter());
Hive.registerAdapter(CardModelAdapter());
Hive.registerAdapter(BankModelAdapter());
Hive.registerAdapter(NotesModelAdapter());
_openBox();
Future _openBox() async
WidgetsFlutterBinding.ensureInitialized();
var dir = await getApplicationDocumentsDirectory();
Hive.init(dir.path);
passwordBox = await Hive.openBox<PasswordModel>('passwordBox');
cardBox = await Hive.openBox<CardModel>('cardBox');
bankBox = await Hive.openBox<BankModel>('bankBox');
notesBox = await Hive.openBox<NotesModel>('notesBox');
return;
//Active Page (Tab)
Widget currentScreen = PasswordsNavigation();
final PageStorageBucket bucket = PageStorageBucket();
Icon cusIcon = Icon(Icons.search);
Widget cusSearchBar = Row(children: [
Text(
"SECRET",
style: TextStyle(color: Colors.orange[900], fontWeight: FontWeight.w700),
),
Text(
"KEEPER",
style: TextStyle(color: Colors.black87, fontWeight: FontWeight.w700),
),
]);
void checkNavigation()
if(currentTab == 0)
Navigator.push(context, MaterialPageRoute(builder: (context) => PasswordInput()));
else if(currentTab == 1)
Navigator.push(context, MaterialPageRoute(builder: (context) => CardInput()));
else if(currentTab == 2)
Navigator.push(context, MaterialPageRoute(builder: (context) => BankInput()));
else
Navigator.push(context, MaterialPageRoute(builder: (context) => NoteInput()));
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: cusSearchBar,
actions: [
IconButton(
onPressed: ()
setState(()
if (this.cusIcon.icon == Icons.search)
this.cusIcon = Icon(Icons.cancel, color: Colors.black87);
this.cusSearchBar = Container(
height: 50,
child: TextField(
textInputAction: TextInputAction.go,
autofocus: true,
decoration: InputDecoration(
border: InputBorder.none, hintText: "Search here"),
style: TextStyle(
fontSize: 20.0,
),
),
);
else
this.cusIcon = Icon(Icons.search);
this.cusSearchBar = Row(children: [
Text(
"SECRET",
style: TextStyle(
color: Colors.orange[900],
fontWeight: FontWeight.w700),
),
Text(
"KEEPER",
style: TextStyle(
color: Colors.black87, fontWeight: FontWeight.w700),
),
]);
);
,
icon: cusIcon,
),
IconButton(
onPressed: () ,
icon: Icon(Icons.more_vert),
),
],
),
body: PageStorage(
child: currentScreen,
bucket: bucket,
),
//FAB Button
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: Colors.orangeAccent,
onPressed: ()
checkNavigation();
,
),
//FAB Position
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
//Bottom App Bar
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
child: Container(
height: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
MaterialButton(
minWidth: 40,
onPressed: ()
setState(()
currentScreen = PasswordsNavigation();
currentTab = 0;
);
,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.paste_sharp,
color: currentTab == 0 ? Colors.orange : Colors.grey,
),
Text(
'Passwords',
style: TextStyle(
color:
currentTab == 0 ? Colors.orange : Colors.grey,
),
),
],
),
),
MaterialButton(
minWidth: 40,
onPressed: ()
setState(()
currentScreen = CardsNavigation();
currentTab = 1;
);
,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.credit_card_rounded,
color: currentTab == 1 ? Colors.orange : Colors.grey,
),
Text(
'Cards',
style: TextStyle(
color:
currentTab == 1 ? Colors.orange : Colors.grey,
),
),
],
),
),
],
),
Row(
children: [
MaterialButton(
minWidth: 40,
onPressed: ()
setState(()
currentScreen = BanksNavigation();
currentTab = 2;
);
,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.food_bank_outlined,
color: currentTab == 2 ? Colors.orange : Colors.grey,
),
Text(
'Banks',
style: TextStyle(
color:
currentTab == 2 ? Colors.orange : Colors.grey,
),
),
],
),
),
MaterialButton(
minWidth: 40,
onPressed: ()
setState(()
currentScreen = NotesNavigation();
currentTab = 3;
);
,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.notes,
color: currentTab == 3 ? Colors.orange : Colors.grey,
),
Text(
'Notes',
style: TextStyle(
color:
currentTab == 3 ? Colors.orange : Colors.grey,
),
),
],
),
),
],
),
],
),
),
),
);
这是我要显示列表的第一个导航屏幕代码:
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:path_provider/path_provider.dart';
import 'package:secret_keeper/Database/Hive/PasswordModel.dart';
import 'package:secret_keeper/screens/home_screen/Home.dart';
class PasswordsNavigation extends StatefulWidget
@override
_PasswordsNavigationState createState() => _PasswordsNavigationState();
class _PasswordsNavigationState extends State<PasswordsNavigation>
@override
void initState()
// TODO: implement initState
super.initState();
// Hive.registerAdapter(PasswordModelAdapter());
_openBox();
Future _openBox() async
WidgetsFlutterBinding.ensureInitialized();
var dir = await getApplicationDocumentsDirectory();
Hive.init(dir.path);
passwordBox = await Hive.openBox<PasswordModel>('passwordBox');
return;
@override
Widget build(BuildContext context)
return Scaffold(
body: Column(
children: [
WatchBoxBuilder(
box: passwordBox,
builder: (context, box)
Map<dynamic, dynamic> raw = box.toMap();
List list = raw.values.toList();
return ListView.builder(
shrinkWrap: true,
itemCount: list.length,
itemBuilder: (context, index)
PasswordModel passwordModel = list[index];
return ListTile(
title: Text(passwordModel.websiteName),
subtitle: Text(passwordModel.websiteAddress),
);
,
);
,
),
],
));
【问题讨论】:
【参考方案1】:我需要一些时间来打开盒子,这就是Hive.openBox
返回Future
的原因。原因是它们的内容仍然需要加载到内存中。因此,第一次显示您的小部件时,它会打开该框,但在初始化变量之前需要一些时间。
与此同时,您必须考虑向用户显示什么:
Widget build(BuildContext context)
if (someBox == null)
return CircularProgressIndicator();
// Here, you can use the box.
...
顺便说一句,我不建议将这些框存储在全局变量中,因为那样会很快变得混乱。使用 Hive,您只需调用一次openBox
。然后,您可以使用Hive.box
同步获取对该框的引用。
因此,您也可以在调用runApp
之前在main
方法中调用Hive.openBox()
。然后,该应用将需要更长的时间才能启动,但您可以随时随地获得所需的数据:
void main()
await Hive.openBox('my-box');
runApp(MyApp());
// elsewhere:
Widget build(BuildContext context)
var box = Hive.box('my-box');
...
对于更复杂的状态管理,您可能也会对上次 Google I/O 中的 State Management video 感兴趣。
【讨论】:
【参考方案2】:替换这个
'
passwordBox = await Hive.openBox<PasswordModel>('passwordBox');
用这个
passwordBox = await Hive.openBox<PasswordModel>('passwordBox');
passwordBox = Hive.box<PasswordModel>('passwordBox');
【讨论】:
github.com/hivedb/hive/issues/358 这个答案解决了我的错误.....以上是关于如何解决 Box not Found 错误 Hive Flutter的主要内容,如果未能解决你的问题,请参考以下文章
Key ssd_300_vgg/block3_box/L2Normalization/gamma not found in checkpoint的解决方案