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

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

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

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

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

avwztpqn1#

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

Widget build(BuildContext context) {
  if (someBox == null) {
    return CircularProgressIndicator();
  }
  // Here, you can use the box.
  ...
}

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

void main() {
  await Hive.openBox('my-box');
  runApp(MyApp());
}

// elsewhere:
Widget build(BuildContext context) {
  var box = Hive.box('my-box');
  ...
}

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

相关问题