#flutter #flutter-hive
#флаттер #флаттер-улей
Вопрос:
Я новичок в Flutter и Hive, только учусь. Вот несколько вопросов:
-
Я использую конструктор прослушиваемых значений, когда я нажимаю «Возраст пользователя» возраст person1 не обновляется, но если я нажимаю setstate, то обновляется. Как выполнить автоматическое обновление?
-
Hive — это база данных; если я нажимаю «Добавить пользователя», он добавляется, и я вижу, когда нажимаю «Напечатать длину пользователя», но при перезагрузке длина пользователя приложения снова изменяется на 1, все добавления удаляются:
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'departmentClass.dart';
import 'person.dart';
void main() async {
await Hive.initFlutter('test');
Hive.registerAdapter(DepartmentAdapter());
Hive.registerAdapter(PersonAdapter());
await Hive.openBox<Department>('testBox');
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final Box testBox = Hive.box<Department>('testBox');
@override
Widget build(BuildContext context) {
if (testBox.isEmpty) {
final List<Person> personsAll = [];
final person1 = new Person(23, "Maria");
personsAll.add(person1);
var mydepartment = new Department(34, "newD", personsAll);
Hive.box<Department>('testBox').put("01", mydepartment);
}
return ValueListenableBuilder(
valueListenable: testBox.listenable(),
builder: (context, box, widget) {
return MaterialApp(
home: SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text("Hive Test"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Hive Sample"),
RaisedButton(
child: Text("Clear Box"),
onPressed: () {
Hive.box<Department>('testBox').clear();
},
),
Text("Person1 Age Now: " box.get("01").persons[0].age.toString()),
RaisedButton(
child: Text("Person age UP"),
onPressed: () {
box.get("01").persons[0].age ;
print(box.get("01").persons[0].age);
},
),
RaisedButton(
child: Text("Set State"),
onPressed: () {
setState(() {});
},
),
RaisedButton(
child: Text("Add person "),
onPressed: () {
final person2 = new Person(23, "Maria");
box.get("01").persons.add(person2);
},
),
RaisedButton(
child: Text("Print person lenght "),
onPressed: () {
print("Persons: " Hive.box<Department>('testBox').get("01").persons.length.toString());
},
)
],
)),
),
),
);
},
);
}
}
Ответ №1:
Прежде всего, когда вы открываете окно, лучше объявить его тип в generic; final Box<Department> testBox = Hive.box<Department>('testBox');
Во-вторых, если вы хотите уведомить окно, через которое вы прослушиваете ValueListenableBuilder
, вам нужно помещать значение внутри поля каждый раз, когда вы меняли значение;
box.get("01").persons[0].age ;
// this will notify the valuelistenablebuilder
box.put("01", box.get("01"));
print(box.get("01").persons[0].age);
Ответ №2:
Я написал приложение, в котором использовал как Hive, так и cubits, и оно работало очень хорошо.
Ниже AppDatabase
приведен класс, в котором у меня есть только один ящик (‘book’), и я открываю его в initialize()
методе, как показано ниже:
Все приложение и руководство здесь.
const String _bookBox = 'book';
@Singleton()
class AppDatabase {
AppDatabase._constructor();
static final AppDatabase _instance = AppDatabase._constructor();
factory AppDatabase() => _instance;
late Box<BookDb> _booksBox;
Future<void> initialize() async {
await Hive.initFlutter();
Hive.registerAdapter<BookDb>(BookDbAdapter());
_booksBox = await Hive.openBox<BookDb>(_bookBox);
}
Future<void> saveBook(Book book) async {
await _booksBox.put(
book.id,
BookDb(
book.id,
book.title,
book.author,
book.publicationDate,
book.about,
book.readAlready,
));
}
Future<void> deleteBook(int id) async {
await _booksBox.delete(id);
}
Future<void> deleteAllBooks() async {
await _booksBox.clear();
}
}