如何解决盒子找不到的错误Hive抖动

kmbjn2e3  于 2021-06-24  发布在  Hive
关注(0)|答案(1)|浏览(394)

我有一个主屏幕,我已经创建了一个4导航屏幕,所以当用户输入登录id和密码,然后它调用主屏幕。但是当用户第一次导航到主屏幕时,它会显示框未初始化,但当我单击底部的导航栏时,它会显示列表,但我想显示列表,即使是用户先登录。
这是我的错误:

以下是用户登录时的主屏幕代码:

  1. import 'package:flutter/material.dart';
  2. import 'package:hive/hive.dart';
  3. import 'package:path_provider/path_provider.dart';
  4. import 'package:secret_keeper/Database/Hive/BankModel.dart';
  5. import 'package:secret_keeper/Database/Hive/CardModel.dart';
  6. import 'package:secret_keeper/Database/Hive/NotesModel.dart';
  7. import 'package:secret_keeper/Database/Hive/PasswordModel.dart';
  8. import 'package:secret_keeper/screens/home_screen/banks/BanksNavigation.dart';
  9. import 'package:secret_keeper/screens/home_screen/cards/CardsNavigation.dart';
  10. import 'package:secret_keeper/screens/home_screen/notes/NotesNavigation.dart';
  11. import 'package:secret_keeper/screens/home_screen/passwords/PasswordsNavigation.dart';
  12. import 'package:secret_keeper/screens/input_screen/bank_input/BankInput.dart';
  13. import 'package:secret_keeper/screens/input_screen/card_input/CardInput.dart';
  14. import 'package:secret_keeper/screens/input_screen/note_input/NoteInput.dart';
  15. import 'package:secret_keeper/screens/input_screen/password_input/PasswordInput.dart';
  16. Box passwordBox, cardBox, bankBox, notesBox;
  17. class Home extends StatefulWidget {
  18. @override
  19. _HomeState createState() => _HomeState();
  20. }
  21. class _HomeState extends State<Home> {
  22. //Properties
  23. int currentTab = 0;
  24. final List<Widget> screens = [
  25. PasswordsNavigation(),
  26. CardsNavigation(),
  27. BanksNavigation(),
  28. NotesNavigation(),
  29. ];
  30. @override
  31. void initState() {
  32. // TODO: implement initState
  33. super.initState();
  34. Hive.registerAdapter(PasswordModelAdapter());
  35. Hive.registerAdapter(CardModelAdapter());
  36. Hive.registerAdapter(BankModelAdapter());
  37. Hive.registerAdapter(NotesModelAdapter());
  38. _openBox();
  39. }
  40. Future _openBox() async {
  41. WidgetsFlutterBinding.ensureInitialized();
  42. var dir = await getApplicationDocumentsDirectory();
  43. Hive.init(dir.path);
  44. passwordBox = await Hive.openBox<PasswordModel>('passwordBox');
  45. cardBox = await Hive.openBox<CardModel>('cardBox');
  46. bankBox = await Hive.openBox<BankModel>('bankBox');
  47. notesBox = await Hive.openBox<NotesModel>('notesBox');
  48. return;
  49. }
  50. //Active Page (Tab)
  51. Widget currentScreen = PasswordsNavigation();
  52. final PageStorageBucket bucket = PageStorageBucket();
  53. Icon cusIcon = Icon(Icons.search);
  54. Widget cusSearchBar = Row(children: [
  55. Text(
  56. "SECRET",
  57. style: TextStyle(color: Colors.orange[900], fontWeight: FontWeight.w700),
  58. ),
  59. Text(
  60. "KEEPER",
  61. style: TextStyle(color: Colors.black87, fontWeight: FontWeight.w700),
  62. ),
  63. ]);
  64. void checkNavigation(){
  65. if(currentTab == 0)
  66. Navigator.push(context, MaterialPageRoute(builder: (context) => PasswordInput()));
  67. else if(currentTab == 1)
  68. Navigator.push(context, MaterialPageRoute(builder: (context) => CardInput()));
  69. else if(currentTab == 2)
  70. Navigator.push(context, MaterialPageRoute(builder: (context) => BankInput()));
  71. else
  72. Navigator.push(context, MaterialPageRoute(builder: (context) => NoteInput()));
  73. }
  74. @override
  75. Widget build(BuildContext context) {
  76. return Scaffold(
  77. appBar: AppBar(
  78. title: cusSearchBar,
  79. actions: [
  80. IconButton(
  81. onPressed: () {
  82. setState(() {
  83. if (this.cusIcon.icon == Icons.search) {
  84. this.cusIcon = Icon(Icons.cancel, color: Colors.black87);
  85. this.cusSearchBar = Container(
  86. height: 50,
  87. child: TextField(
  88. textInputAction: TextInputAction.go,
  89. autofocus: true,
  90. decoration: InputDecoration(
  91. border: InputBorder.none, hintText: "Search here"),
  92. style: TextStyle(
  93. fontSize: 20.0,
  94. ),
  95. ),
  96. );
  97. } else {
  98. this.cusIcon = Icon(Icons.search);
  99. this.cusSearchBar = Row(children: [
  100. Text(
  101. "SECRET",
  102. style: TextStyle(
  103. color: Colors.orange[900],
  104. fontWeight: FontWeight.w700),
  105. ),
  106. Text(
  107. "KEEPER",
  108. style: TextStyle(
  109. color: Colors.black87, fontWeight: FontWeight.w700),
  110. ),
  111. ]);
  112. }
  113. });
  114. },
  115. icon: cusIcon,
  116. ),
  117. IconButton(
  118. onPressed: () {},
  119. icon: Icon(Icons.more_vert),
  120. ),
  121. ],
  122. ),
  123. body: PageStorage(
  124. child: currentScreen,
  125. bucket: bucket,
  126. ),
  127. //FAB Button
  128. floatingActionButton: FloatingActionButton(
  129. child: Icon(Icons.add),
  130. backgroundColor: Colors.orangeAccent,
  131. onPressed: () {
  132. checkNavigation();
  133. },
  134. ),
  135. //FAB Position
  136. floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
  137. //Bottom App Bar
  138. bottomNavigationBar: BottomAppBar(
  139. shape: CircularNotchedRectangle(),
  140. child: Container(
  141. height: 60,
  142. child: Row(
  143. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  144. children: [
  145. Row(
  146. children: [
  147. MaterialButton(
  148. minWidth: 40,
  149. onPressed: () {
  150. setState(() {
  151. currentScreen = PasswordsNavigation();
  152. currentTab = 0;
  153. });
  154. },
  155. child: Column(
  156. mainAxisAlignment: MainAxisAlignment.center,
  157. children: [
  158. Icon(
  159. Icons.paste_sharp,
  160. color: currentTab == 0 ? Colors.orange : Colors.grey,
  161. ),
  162. Text(
  163. 'Passwords',
  164. style: TextStyle(
  165. color:
  166. currentTab == 0 ? Colors.orange : Colors.grey,
  167. ),
  168. ),
  169. ],
  170. ),
  171. ),
  172. MaterialButton(
  173. minWidth: 40,
  174. onPressed: () {
  175. setState(() {
  176. currentScreen = CardsNavigation();
  177. currentTab = 1;
  178. });
  179. },
  180. child: Column(
  181. mainAxisAlignment: MainAxisAlignment.center,
  182. children: [
  183. Icon(
  184. Icons.credit_card_rounded,
  185. color: currentTab == 1 ? Colors.orange : Colors.grey,
  186. ),
  187. Text(
  188. 'Cards',
  189. style: TextStyle(
  190. color:
  191. currentTab == 1 ? Colors.orange : Colors.grey,
  192. ),
  193. ),
  194. ],
  195. ),
  196. ),
  197. ],
  198. ),
  199. Row(
  200. children: [
  201. MaterialButton(
  202. minWidth: 40,
  203. onPressed: () {
  204. setState(() {
  205. currentScreen = BanksNavigation();
  206. currentTab = 2;
  207. });
  208. },
  209. child: Column(
  210. mainAxisAlignment: MainAxisAlignment.center,
  211. children: [
  212. Icon(
  213. Icons.food_bank_outlined,
  214. color: currentTab == 2 ? Colors.orange : Colors.grey,
  215. ),
  216. Text(
  217. 'Banks',
  218. style: TextStyle(
  219. color:
  220. currentTab == 2 ? Colors.orange : Colors.grey,
  221. ),
  222. ),
  223. ],
  224. ),
  225. ),
  226. MaterialButton(
  227. minWidth: 40,
  228. onPressed: () {
  229. setState(() {
  230. currentScreen = NotesNavigation();
  231. currentTab = 3;
  232. });
  233. },
  234. child: Column(
  235. mainAxisAlignment: MainAxisAlignment.center,
  236. children: [
  237. Icon(
  238. Icons.notes,
  239. color: currentTab == 3 ? Colors.orange : Colors.grey,
  240. ),
  241. Text(
  242. 'Notes',
  243. style: TextStyle(
  244. color:
  245. currentTab == 3 ? Colors.orange : Colors.grey,
  246. ),
  247. ),
  248. ],
  249. ),
  250. ),
  251. ],
  252. ),
  253. ],
  254. ),
  255. ),
  256. ),
  257. );
  258. }
  259. }

这是我的第一个导航屏幕代码,我想在其中显示列表:

  1. import 'package:flutter/material.dart';
  2. import 'package:hive/hive.dart';
  3. import 'package:hive_flutter/hive_flutter.dart';
  4. import 'package:path_provider/path_provider.dart';
  5. import 'package:secret_keeper/Database/Hive/PasswordModel.dart';
  6. import 'package:secret_keeper/screens/home_screen/Home.dart';
  7. class PasswordsNavigation extends StatefulWidget {
  8. @override
  9. _PasswordsNavigationState createState() => _PasswordsNavigationState();
  10. }
  11. class _PasswordsNavigationState extends State<PasswordsNavigation> {
  12. @override
  13. void initState() {
  14. // TODO: implement initState
  15. super.initState();
  16. // Hive.registerAdapter(PasswordModelAdapter());
  17. _openBox();
  18. }
  19. Future _openBox() async {
  20. WidgetsFlutterBinding.ensureInitialized();
  21. var dir = await getApplicationDocumentsDirectory();
  22. Hive.init(dir.path);
  23. passwordBox = await Hive.openBox<PasswordModel>('passwordBox');
  24. return;
  25. }
  26. @override
  27. Widget build(BuildContext context) {
  28. return Scaffold(
  29. body: Column(
  30. children: [
  31. WatchBoxBuilder(
  32. box: passwordBox,
  33. builder: (context, box) {
  34. Map<dynamic, dynamic> raw = box.toMap();
  35. List list = raw.values.toList();
  36. return ListView.builder(
  37. shrinkWrap: true,
  38. itemCount: list.length,
  39. itemBuilder: (context, index) {
  40. PasswordModel passwordModel = list[index];
  41. return ListTile(
  42. title: Text(passwordModel.websiteName),
  43. subtitle: Text(passwordModel.websiteAddress),
  44. );
  45. },
  46. );
  47. },
  48. ),
  49. ],
  50. ));
  51. }
  52. }
avwztpqn

avwztpqn1#

我花了些时间打开箱子,这就是为什么 Hive.openBox 返回一个 Future . 原因是它们的内容仍然需要加载到内存中。因此,第一次显示小部件时,它会打开框,但初始化变量需要一些时间。
在此期间,您必须考虑向用户显示什么:

  1. Widget build(BuildContext context) {
  2. if (someBox == null) {
  3. return CircularProgressIndicator();
  4. }
  5. // Here, you can use the box.
  6. ...
  7. }

顺便说一句,我不建议将框存储在全局变量中,因为这样会很快变得混乱。使用Hive,你只需要打电话 openBox 一次。然后,可以使用 Hive.box .
所以,你也可以打电话 Hive.openBox() 在你的 main -调用前的方法 runApp . 然后,应用程序将需要更长的时间来启动,但您可以在任何需要的地方随时获取数据:

  1. void main() {
  2. await Hive.openBox('my-box');
  3. runApp(MyApp());
  4. }
  5. // elsewhere:
  6. Widget build(BuildContext context) {
  7. var box = Hive.box('my-box');
  8. ...
  9. }

对于更复杂的状态管理,来自上一次google i/o的状态管理视频可能也会引起您的兴趣。

展开查看全部

相关问题