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