Home > database >  Flutter - GridView & StreamBuilder with Firebase Realtime DB
Flutter - GridView & StreamBuilder with Firebase Realtime DB

Time:04-25

I'm trying to learn about how can I insert my Image URLs -which are stored in my Firebase Realtime DB as image_cat key's value as string type- to GridView.

My DB structuse is like:

{
  "Products": {
    "Baby": {
      "image_cat": "https://url1.com"
    },
    "Beauty": {
      "image_cat": "https://url2.com"
    },
    "Grocery": {
      "image_cat": "https://url3.com"
    }
  }
}

I've written a code like this;

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

As I shown with forEach in the code, I can get my whole URLs one by one. But I don't know how can I insert them in to GridView. I need to use them in my NetworkImage widget.

1)How can I do that? 2)Also, is there any way to prevent to use 2 forEach? or any more better performanced way?

CodePudding user response:

You can create a List and add each Image-URL to it, and use it in the GridView.builder

like this:

List images = [];
final myuser = snapshot.data!.snapshot;

             myuser.children.forEach((element) {
               element.children.forEach((element2) {
                 if(element2.key == "image_cat"){
                   images.add(element2.value);

                 }
               });
            });

and to use them in the GridView.builder you need to specify the itemCount as the images list length, and u can access each item in the list by the index that is provided by the 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,
                      );
                    });
              }
  • Related