Flutter 配置单元数据库不保存嵌套对象
你好,我有一个应用程序,用户可以创建主要类别的子类别。当用户创建主类别时,主对象保存到数据库中,在我重新打开应用程序后,我可以看到它们,但当我为指定主类别的子类别创建时,我可以在子类别屏幕中看到,但当我重新打开应用程序时,我可以看到唯一的主类别,我猜子类别无法保存到数据库中,我使用Hive将数据存储到手机中,有人能解释一下为什么我不能将子对象保存到DB中,以及我如何做到这一点。我结巴了谢谢你的帮助 我共享主类别屏幕,使em显示主类别Flutter 配置单元数据库不保存嵌套对象,flutter,Flutter,你好,我有一个应用程序,用户可以创建主要类别的子类别。当用户创建主类别时,主对象保存到数据库中,在我重新打开应用程序后,我可以看到它们,但当我为指定主类别的子类别创建时,我可以在子类别屏幕中看到,但当我重新打开应用程序时,我可以看到唯一的主类别,我猜子类别无法保存到数据库中,我使用Hive将数据存储到手机中,有人能解释一下为什么我不能将子对象保存到DB中,以及我如何做到这一点。我结巴了谢谢你的帮助 我共享主类别屏幕,使em显示主类别 class HomeScreen extends Statef
class HomeScreen extends StatefulWidget {
HomeScreen({this.newCategoryName,this.newCategoryImagePath});
final String newCategoryImagePath;
final String newCategoryName;
static String id="homeScreen";
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Widget buildBottomSheet(BuildContext context)=>AddMenuScreen(buttonText: "Menü Ekle",route: "homeScreen");
int _flag=0;
Box<CategoryModel> _categoryModelsBox;
void initState(){
super.initState();
_categoryModelsBox = Hive.box<CategoryModel>("categoryModelsInBox");
if (widget.newCategoryName!=null && widget.newCategoryImagePath!=null){
CategoryModel newCategoryModel = CategoryModel(categoryId:categoryModels.length, categoryImagePath: widget.newCategoryImagePath,
categoryName: widget.newCategoryName,categoryColor: Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(0.5).value);
categoryModels.insert(categoryModels.length,newCategoryModel);
_categoryModelsBox.add(newCategoryModel);
}
}
Future<bool> showAlertDialog(BuildContext context){
AlertDialog alert = AlertDialog(
backgroundColor: kColorTheme10,
elevation: 0,
content: Container(decoration:BoxDecoration(
border: Border.all(style: BorderStyle.solid,width: 1),
color: Colors.white70.withOpacity(0.7),
borderRadius: BorderRadius.circular(15)
), child: Padding(
padding: EdgeInsets.all(8.0),
child: Text(
"Çıkmak istediğinizden emin misiniz?",
style: TextStyle(
fontSize: 25,
fontFamily: "OpenSans")
),
),
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
actions: [
Container(
decoration: BoxDecoration(
color: Colors.white70.withOpacity(0.7),
borderRadius: BorderRadius.circular(30)
),
child: TextButton(onPressed:()async{
Navigator.of(context).pop(true);
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text("EVET",style: TextStyle(fontWeight: FontWeight.bold,fontFamily: "OpenSans"),),
)),
),
Container(
decoration: BoxDecoration(
color:Colors.white70.withOpacity(0.7),
borderRadius: BorderRadius.circular(30)
),
child: TextButton(onPressed:()async{
Navigator.of(context).pop(false);
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text("HAYIR",style: TextStyle(fontWeight: FontWeight.bold, fontFamily: "OpenSans")),
),
),
),
],
);
return showDialog(
context: context,
builder: (_)=>alert);
}
@override
Widget build(BuildContext context) {
return WillPopScope(
child: SafeArea(
child: Scaffold(
backgroundColor: kColorTheme1,
appBar: AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
elevation: 20,
backgroundColor: Color(0xFFF2C3D4).withOpacity(1),
title:TitleBorderedText(title:"Sevimli Yemekler", textColor: Color(0xFFFFFB00)),
actions: [
CircleAvatar(
radius: 27,
backgroundColor: Colors.transparent,
backgroundImage: AssetImage(kCuttedLogoPath),
),
],
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(kBGWithLogoOpacity),
fit: BoxFit.cover,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child:GridView.builder (
scrollDirection: Axis.vertical,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount: _categoryModelsBox.length+1,
itemBuilder: (context,index) {
if(_categoryModelsBox.length==0){
return EmptyCard(where: "homeScreen",);
}
if(_flag==1){
return EmptyCard(where: "homeScreen",);
}
if(index==_categoryModelsBox.length-1){
_flag=1;
CategoryModel categoryModel = _categoryModelsBox.getAt(index);
return CategoryCard(category: categoryModel);
}
else{
CategoryModel categoryModel = _categoryModelsBox.getAt(index);
return CategoryCard(category: categoryModel);
}
}
),
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
border: Border.all(style: BorderStyle.solid),
color: kColorTheme7,
borderRadius: BorderRadius.circular(40),
),
child: TextButton(
onPressed: (){
showModalBottomSheet(
isDismissible: false,
enableDrag: false,
context: context,
builder: (BuildContext context)=> AddMenuScreen(buttonText: "Menü Ekle",route: "homeScreen",),
);
},
child: TitleBorderedText(title: "LEZZET GRUBU EKLE",textColor: Colors.white,)
),
),
),
],
)
],
),
)
),
),
onWillPop: ()async{
var response = await showAlertDialog(context);
print(response);
return response;
},
);
}
}
类主屏幕扩展StatefulWidget{
主屏幕({this.newCategoryName,this.newCategoryImagePath});
最终字符串newCategoryImagePath;
最终字符串newCategoryName;
静态字符串id=“主屏幕”;
@凌驾
_HomeScreenState createState()=>\u HomeScreenState();
}
类_homescrenstate扩展状态{
小部件buildBottomSheet(BuildContext上下文)=>AddMenuScreen(按钮文本:“MenüEkle”,路径:“主屏幕”);
int _标志=0;
箱子(类别)模型箱;;
void initState(){
super.initState();
_categoryModelsBox=Hive.box(“categoryModelsBox”);
if(widget.newCategoryName!=null&&widget.newCategoryImagePath!=null){
CategoryModel newCategoryModel=CategoryModel(categoryId:categoryModels.length,categoryImagePath:widget.newCategoryImagePath,
categoryName:widget.newCategoryName,categoryColor:Color((Random().nextDouble()*0xFFFFFF).toInt())。不透明度(0.5).value);
categoryModels.insert(categoryModels.length,newCategoryModel);
_添加(newCategoryModel);
}
}
Future showAlertDialog(构建上下文){
AlertDialog alert=AlertDialog(
背景颜色:kColorTheme10,
海拔:0,
内容:容器(装饰:盒子装饰)(
边框:边框。全部(样式:边框样式。实心,宽度:1),
颜色:颜色。白色70。不透明度(0.7),
边界半径:边界半径。圆形(15)
),child:Padding(
填充:边缘设置。全部(8.0),
子:文本(
“ıkmak istediğinden emin Misiz?”,
样式:TextStyle(
尺寸:25,
fontFamily:“OpenSAN”)
),
),
),
形状:RoundedRectangleBorder(borderRadius:borderRadius.circular(30)),
行动:[
容器(
装饰:盒子装饰(
颜色:颜色。白色70。不透明度(0.7),
边界半径:边界半径。圆形(30)
),
子项:文本按钮(按下时:()异步{
Navigator.of(context.pop)(true);
},
孩子:填充(
填充:常数边集全部(8.0),
子项:文本(“EVET”,样式:TextStyle(fontWeight:fontWeight.bold,fontFamily:“OpenSans”),
)),
),
容器(
装饰:盒子装饰(
颜色:颜色。白色70。不透明度(0.7),
边界半径:边界半径。圆形(30)
),
子项:文本按钮(按下时:()异步{
Navigator.of(context.pop)(false);
},
孩子:填充(
填充:常数边集全部(8.0),
子项:文本(“HAYIR”,样式:TextStyle(fontWeight:fontWeight.bold,fontFamily:“OpenSans”),
),
),
),
],
);
返回显示对话框(
上下文:上下文,
生成器:()=>警报);
}
@凌驾
小部件构建(构建上下文){
返回式示波器(
儿童:安全区(
孩子:脚手架(
背景颜色:kColorTheme1,
appBar:appBar(
标题:对,
自动嵌入:false,
海拔:20,
背景颜色:颜色(0xFFF2C3D4)。不透明度(1),
标题:标题有序文本(标题:“Sevimli Yemekler”,文本颜色:颜色(0xFFFFFB00)),
行动:[
圆形(
半径:27,
背景颜色:颜色。透明,
背景图片:AssetImage(kCuttedLogoPath),
),
],
),
主体:容器(
装饰:盒子装饰(
图像:装饰图像(
图像:AssetImage(kBGWithLogoOpacity),
适合:BoxFit.cover,
),
),
子:列(
crossAxisAlignment:crossAxisAlignment.stretch,
儿童:[
扩大(
子项:GridView.builder(
滚动方向:轴垂直,
gridDelegate:SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2),
itemCount:_categoryModelsBox.length+1,
itemBuilder:(上下文,索引){
如果(_categoryModelsBox.length==0){
返回空卡片(其中:“主屏幕”);
}
如果(_标志==1){
返回空卡片(其中:“主屏幕”);
}
如果(索引==_categoryModelsBox.length-1){
_flag=1;
CategoryModel CategoryModel=\u categoryModelsBox.getAt(索引);
返回CategoryCard(类别:categoryModel);
}
否则{
CategoryModel CategoryModel=\u categoryModelsBox.getAt(索引);
返回CategoryCard(类别:categoryModel);
}
}
class SubCategoriesScreen extends StatefulWidget {
SubCategoriesScreen({this.categoryId,this.subCategoryName, this.subCategoryImagePath});
static String id="subCategoriesScreen";
final String subCategoryName;
final String subCategoryImagePath;
final int categoryId;
Widget buildBottomSheet(BuildContext context)=>AddMenuScreen(categoryId: categoryId,buttonText: "Tarif Ekle",route: "subCategoryScreen",);
@override
_SubCategoriesScreenState createState() => _SubCategoriesScreenState();
}
class _SubCategoriesScreenState extends State<SubCategoriesScreen> {
int _flag=0;
Box<CategoryModel> _categoryModelBox;
CategoryModel _categoryModel;
void initState(){
super.initState();
_categoryModelBox = Hive.box<CategoryModel>("categoryModelsInBox");
_categoryModel = _categoryModelBox.getAt(widget.categoryId);
if(widget.categoryId!=null && widget.subCategoryImagePath!=null && widget.subCategoryName!=null){
addSubCategory();
}
}
void addSubCategory()async{
SubCategoryModel subCategoryModel=SubCategoryModel(
subCategoryId:widget.categoryId,
subCategoryImagePath: widget.subCategoryImagePath,
subCategoryName: widget.subCategoryName,
categoryColor: Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(0.5).value);
if(_categoryModel.subCategoryModels!=null){
//for (var categoryModel in categoryModels){
//if (categoryModel.categoryId == subCategoryModel.subCategoryId){
//categoryModel.subCategoryModels.insert(categoryModel.subCategoryModels.length-1,subCategoryModel);
//categoryModel.subCategoryModels.add(subCategoryModel);
_categoryModel=_categoryModelBox.getAt(widget.categoryId);
_categoryModel.subCategoryModels.add(subCategoryModel);
_categoryModelBox.putAt(widget.categoryId, _categoryModel);
//}
//}
}
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
title: BorderedText(
child:Text(
_categoryModel.categoryName,
style: TextStyle(
color: Color(0XFFFFFB00),
fontSize: 30,
fontFamily: "OpenSans"
),
),
strokeWidth: 5,
strokeColor: Colors.black,
),
elevation: 5,
backgroundColor: Color(0xFFF2C3D4).withOpacity(1),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: (){
Navigator.pop(context);
},
iconSize: 40,
color: Color(0xFFA2000B),
),
actions: [
CircleAvatar(
radius: 27,
backgroundColor: Colors.transparent,
backgroundImage: AssetImage("images/cuttedlogo.PNG"),
)
],
),
body:Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/logoBGopacity.png"),
fit: BoxFit.cover,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: GridView.builder(
scrollDirection: Axis.vertical,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount:_categoryModel.subCategoryModels.length+1,
itemBuilder: (context,index){
if(_categoryModel.subCategoryModels.length==0){
return EmptyCard(where: "subCategoryScreen",categoryId: widget.categoryId,);
}
if(_flag==1){
return EmptyCard(where: "subCategoryScreen",categoryId: widget.categoryId,);
}
if(index==_categoryModel.subCategoryModels.length-1){
_flag=1;
SubCategoryModel subCategoryModel =_categoryModel.subCategoryModels[index];
return SubCategoryCard(subCategoryCardId:index,subCategoryId:subCategoryModel.subCategoryId,subcategoryName: subCategoryModel.subCategoryName,
subCategoryImagePath:subCategoryModel.subCategoryImagePath,
subCategoryCardColor: subCategoryModel.categoryColor,);
}
else{
SubCategoryModel subCategoryModel =_categoryModel.subCategoryModels[index];
return SubCategoryCard(subCategoryCardId:index,subCategoryId:subCategoryModel.subCategoryId,subcategoryName: subCategoryModel.subCategoryName,
subCategoryImagePath:subCategoryModel.subCategoryImagePath,
subCategoryCardColor: subCategoryModel.categoryColor,);
}
}
),
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
border: Border.all(style: BorderStyle.solid),
color: kColorTheme7,
borderRadius: BorderRadius.circular(40),
),
child: TextButton(
onPressed: (){
showModalBottomSheet(
isDismissible: false,
enableDrag: false,
context: context,
builder: (BuildContext context)=> AddMenuScreen(categoryId:widget.categoryId,buttonText: "Tarif Ekle", route:"subCategoryScreen"),
);
},
child: BorderedText(
strokeWidth: 5,
strokeColor: Colors.black,
child:Text("Tarif Ekle",style: TextStyle(
color: Colors.white,
fontFamily:'OpenSans',
fontSize:30,
),
),
),
),
),
),
],
)
],
),
),
)
),
);
}
}
part 'categoryModel.g.dart';
@HiveType(typeId : 0)
class CategoryModel extends HiveObject{
CategoryModel(
{ this.categoryId,
this.categoryImagePath,
this.categoryName,
this.categoryColor});
@HiveField(0)
final int categoryColor;
@HiveField(1)
List <SubCategoryModel> subCategoryModels=[];
@HiveField(2)
int categoryId;
@HiveField(3)
String categoryImagePath;
@HiveField(4)
String categoryName;
}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'categoryModel.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class CategoryModelAdapter extends TypeAdapter<CategoryModel> {
@override
final int typeId = 1;
@override
CategoryModel read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return CategoryModel(
categoryId: fields[2] as int,
categoryImagePath: fields[3] as String,
categoryName: fields[4] as String,
categoryColor: fields[0] as int,
//subCategoryModels: (fields[1] as List)?.cast<SubCategoryModel>()
);
}
@override
void write(BinaryWriter writer, CategoryModel obj) {
writer
..writeByte(5)
..writeByte(0)
..write(obj.categoryColor)
..writeByte(1)
..write(obj.subCategoryModels)
..writeByte(2)
..write(obj.categoryId)
..writeByte(3)
..write(obj.categoryImagePath)
..writeByte(4)
..write(obj.categoryName);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is CategoryModelAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
part 'subCategoryModel.g.dart';
@HiveType(typeId : 1)
class SubCategoryModel extends HiveObject{
SubCategoryModel({
this.subCategoryId,
this.subCategoryImagePath,
this.subCategoryName,
this.categoryColor,
this.recipeId,
List<Ingredient>ingredients,
this.recipePhotoDir,
this.recordedVoiceDir,
bool isCompeted});
@HiveField(0)
final int categoryColor;
@HiveField(1)
final double recipeId;
@HiveField(2)
bool isCompleted;
@HiveField(3)
int subCategoryId;
@HiveField(4)
String subCategoryImagePath;
@HiveField(5)
String subCategoryName;
@HiveField(6)
List <Ingredient> ingredients=[] ;
@HiveField(7)
String recipePhotoDir;
@HiveField(8)
String recordedVoiceDir;
}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'subCategoryModel.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class SubCategoryModelAdapter extends TypeAdapter<SubCategoryModel> {
@override
final int typeId = 2;
@override
SubCategoryModel read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return SubCategoryModel(
subCategoryId: fields[3] as int,
subCategoryImagePath: fields[4] as String,
subCategoryName: fields[5] as String,
categoryColor: fields[0] as int,
recipeId: fields[1] as double,
ingredients: (fields[6] as List)?.cast<Ingredient>(),
recipePhotoDir: fields[7] as String,
recordedVoiceDir: fields[8] as String,
)..isCompleted = fields[2] as bool;
}
Hive.registerAdapter(ChildAdapter());
Hive.registerAdapter(ParentAdapter());
Hive.registerAdapter(ParentAdapter());
Hive.registerAdapter(ChildAdapter());