Flutter - 带有 Firebase 实时数据库的 GridView 和 StreamBuilder
Flutter - GridView & StreamBuilder with Firebase Realtime DB
我正在尝试了解如何将我的图像 URL(存储在我的 Firebase 实时数据库中,作为 image_cat
键值作为字符串类型)插入 GridView。
我的数据库结构是这样的:
{
"Products": {
"Baby": {
"image_cat": "https://url1.com"
},
"Beauty": {
"image_cat": "https://url2.com"
},
"Grocery": {
"image_cat": "https://url3.com"
}
}
}
我写过这样的代码;
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
class MyScreen extends StatefulWidget {
static const String idScreen = "myScreen";
@override
_MyScreenState createState() => _MyScreenState();
}
class _MyScreenState extends State<MyScreen> {
final database = FirebaseDatabase.instance.ref("Products");
@override
Widget build(BuildContext context) {
final mainuserlist = database.onValue;
return Scaffold(
backgroundColor: Colors.yellow,
body: SafeArea(
child: Column(children: [
Expanded(
child: StreamBuilder<DatabaseEvent>(
stream: mainuserlist,
builder: (context, snapshot) {
if (snapshot.hasData) {
final myuser = snapshot.data!.snapshot;
myuser.children.forEach((element) {
element.children.forEach((element2) {
if(element2.key == "image_cat"){
print(element2.value); // HERE I CAN GET MY WHOLE IMAGE URLS
}
});
});
return GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
mainAxisExtent: 200,
maxCrossAxisExtent: 150,
crossAxisSpacing: 5,
mainAxisSpacing: 5),
itemCount: 10,
itemBuilder: (context, count) {
return Transform(
child: SizedBox(
width: 80,
height: 80,
child: CircleAvatar(
radius: 25,
backgroundImage: NetworkImage("?") // I NEED TO USE IN HERE
),
),
transform: Matrix4.rotationZ(-0.2),
alignment: FractionalOffset.centerRight,
);
});
}
return Center(child: CircularProgressIndicator());
}),
)
]),
),
);
}
}
正如我在代码中使用 forEach 所示,我可以一个一个地获取我的整个 URL。但我不知道如何将它们插入到 GridView 中。我需要在我的 NetworkImage 小部件中使用它们。
1)我该怎么做?
2)另外,有什么办法可以防止使用 2 forEach 吗?或任何更好的性能方式?
您可以创建一个列表并将每个 Image-URL 添加到其中,然后在 GridView.builder
中使用它
像这样:
List images = [];
final myuser = snapshot.data!.snapshot;
myuser.children.forEach((element) {
element.children.forEach((element2) {
if(element2.key == "image_cat"){
images.add(element2.value);
}
});
});
要在 GridView.builder
中使用它们,您需要将 itemCount 指定为图像列表长度,并且您可以通过 GridView.builder
提供的索引访问列表中的每个项目:
GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
itemCount: images.length,
itemBuilder: (context, count) {
return Transform(
child: SizedBox(
width: 80,
height: 80,
child: CircleAvatar(
radius: 25,
backgroundImage: NetworkImage(images[count]) // I NEED TO USE IN HERE
),
),
transform: Matrix4.rotationZ(-0.2),
alignment: FractionalOffset.centerRight,
);
}
);
)
我正在尝试了解如何将我的图像 URL(存储在我的 Firebase 实时数据库中,作为 image_cat
键值作为字符串类型)插入 GridView。
我的数据库结构是这样的:
{
"Products": {
"Baby": {
"image_cat": "https://url1.com"
},
"Beauty": {
"image_cat": "https://url2.com"
},
"Grocery": {
"image_cat": "https://url3.com"
}
}
}
我写过这样的代码;
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
class MyScreen extends StatefulWidget {
static const String idScreen = "myScreen";
@override
_MyScreenState createState() => _MyScreenState();
}
class _MyScreenState extends State<MyScreen> {
final database = FirebaseDatabase.instance.ref("Products");
@override
Widget build(BuildContext context) {
final mainuserlist = database.onValue;
return Scaffold(
backgroundColor: Colors.yellow,
body: SafeArea(
child: Column(children: [
Expanded(
child: StreamBuilder<DatabaseEvent>(
stream: mainuserlist,
builder: (context, snapshot) {
if (snapshot.hasData) {
final myuser = snapshot.data!.snapshot;
myuser.children.forEach((element) {
element.children.forEach((element2) {
if(element2.key == "image_cat"){
print(element2.value); // HERE I CAN GET MY WHOLE IMAGE URLS
}
});
});
return GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
mainAxisExtent: 200,
maxCrossAxisExtent: 150,
crossAxisSpacing: 5,
mainAxisSpacing: 5),
itemCount: 10,
itemBuilder: (context, count) {
return Transform(
child: SizedBox(
width: 80,
height: 80,
child: CircleAvatar(
radius: 25,
backgroundImage: NetworkImage("?") // I NEED TO USE IN HERE
),
),
transform: Matrix4.rotationZ(-0.2),
alignment: FractionalOffset.centerRight,
);
});
}
return Center(child: CircularProgressIndicator());
}),
)
]),
),
);
}
}
正如我在代码中使用 forEach 所示,我可以一个一个地获取我的整个 URL。但我不知道如何将它们插入到 GridView 中。我需要在我的 NetworkImage 小部件中使用它们。
1)我该怎么做? 2)另外,有什么办法可以防止使用 2 forEach 吗?或任何更好的性能方式?
您可以创建一个列表并将每个 Image-URL 添加到其中,然后在 GridView.builder
像这样:
List images = [];
final myuser = snapshot.data!.snapshot;
myuser.children.forEach((element) {
element.children.forEach((element2) {
if(element2.key == "image_cat"){
images.add(element2.value);
}
});
});
要在 GridView.builder
中使用它们,您需要将 itemCount 指定为图像列表长度,并且您可以通过 GridView.builder
提供的索引访问列表中的每个项目:
GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
itemCount: images.length,
itemBuilder: (context, count) {
return Transform(
child: SizedBox(
width: 80,
height: 80,
child: CircleAvatar(
radius: 25,
backgroundImage: NetworkImage(images[count]) // I NEED TO USE IN HERE
),
),
transform: Matrix4.rotationZ(-0.2),
alignment: FractionalOffset.centerRight,
);
}
);
)