Search code examples
flutterdartflutter-layoutflutter-gridview

not able to return elements with nested gridview builder - fluttter


my case is that I am retrieving values images and text for challenges (like products ...etc), the challenges should appear one by one vertically first the image appears then the text appears over the image in the centre so I used stack and padding and I was able to retrieve one challenge information only, now I want to retrieve all challenges vertically using gridview builder, so I have did this :

 Widget build(BuildContext context) {
    return GridView.builder(
        scrollDirection: Axis.vertical,
        gridDelegate:
            SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: _challenges.length),
        itemBuilder: (_, index) {
          return InkWell(
            onTap: () {},
            child: Stack(
              children: [
                Padding(
                  padding: EdgeInsets.all(10.0),
                  child: Center(
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(15),
                      child: Image(
                        image:
                            NetworkImage(_challenges[index]["image-path"][0]),
                        fit: BoxFit.cover,
                        height: 150,
                        width: 350,
                        opacity: AlwaysStoppedAnimation(.4),
                      ),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(60.0),
                  child: Center(
                    child: Text(
                      "${_challenges[index]["name"]}\n${_challenges[index]["date"]}",
                      style: TextStyle(
                          color: Colors.white,
                          fontSize: 20,
                          fontWeight: FontWeight.bold),
                    ),
                  ),
                ),
              ],
            ),
          );
        });

every time i hot reload the app i get this error:

'package:flutter/src/rendering/sliver_grid.dart': Failed assertion: line 319 pos 15: 'crossAxisCount != null && crossAxisCount > 0': is not true.

and in just in case this is how i retrieved the data from Firestore:

 List _challenges = [];

  fetchChallengeData() async {
    var _fireStoreInstance = FirebaseFirestore.instance;
    QuerySnapshot qn = await _fireStoreInstance.collection("challenges").get();

    setState(() {
      for (int i = 0; i < qn.docs.length; i++) {
        _challenges.add({
          "image-path": qn.docs[i]["image-path"],
          "name": qn.docs[i]["name"],
          "date": qn.docs[i]["date"],
        });
      }
    });
  }

  @override
  void initState() {
    fetchChallengeData();

    super.initState();
  }

the home screen where i use to display the element looks like:

return Scaffold(
    appBar: AppBar(
      backgroundColor: Colors.purple,
      title: Text(
        "أتحداك",
        style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
      ),
      centerTitle: true,
    ),
    body: SingleChildScrollView(
      child: Column(
        children: [
          AdsBanner(),
          SizedBox(
            height: 50,
          ),
          Directionality(
            textDirection: TextDirection.rtl,
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                children: [
                  Text(
                    "التحديات",
                    style: TextStyle(fontSize: 20),
                  ),
                  Text(
                    " (إضغط على التحدي للإشتراك به)",
                    style: TextStyle(fontSize: 15),
                  )
                ],
              ),
            ),
          ),
          ChallengeCard(),
        ],
      ),
    ),
    endDrawer: NavigationDrawer());

so basically the parent is a column and the parent of the column is singleChildScrollView,

any help I would be grateful, Thanks.


Solution

  • We are getting data from future fetchChallengeData, So it will be null initially, Try returning another widget on null or empty cases

     Widget build(BuildContext context) {
        return _challenges!=null && _challenges.isNotEmpty? GridView.builder(...): SizedBox.shrink();
    

    Though _challenges.isNotEmpty enough while we've List _challenges = [];

    I think we are seeking somthing like this

      Widget myGridView() {
        return GridView.builder(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 4, //number of items on single Row
          ),
          itemCount: _challenges.length, // number of item will render
          itemBuilder: (context, index) => Text("Your item Builder"),
        );
      }
    

    Widget placement

     body: Column(
            children: [
              AdsBanner(),
              SizedBox(
                height: 50,
              ),
              Directionality(
                textDirection: TextDirection.rtl,
                child: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Row(
                    children: [
                      Text(
                        "التحديات",
                        style: TextStyle(fontSize: 20),
                      ),
                      Text(
                        " (إضغط على التحدي للإشتراك به)",
                        style: TextStyle(fontSize: 15),
                      )
                    ],
                  ),
                ),
              ),
             Expanded(child: ChallengeCard()),
            ],
          ),