Search code examples
flutterdartgridview.builder

When use a GridView.builder the alignment of all the other widgets get compromised. what can I do in this situation?


I am trying to use

GridView.builder() 

method to generate a grid of subcategory items inside my HomePage. but every time I use the GridView.builder inside the HomePage the alignments of all the other widgets become problematic.

when I comment the GridView.builder or when I use GridView.builder on another test page it works as intended.

I have attached some screenshots so that you could understand what I am saying.

This image shows how the widgets are aligned when I comment out the GridView.builder.

this is when I comment out the GridView.builder - everything works fine

when I enable the GridView.builder it goes like this

this is how it goes when I enable the GridView.builder

the code for the HomePage():

import 'package:flutter/material.dart';
import 'package:foodie_mobile_application/classes/burger_class.dart';
import 'package:foodie_mobile_application/colors.dart';
import 'package:foodie_mobile_application/components/custom_button.dart';
import 'package:foodie_mobile_application/components/main_category_widget.dart';
import 'package:foodie_mobile_application/components/sub_category_custom_gridView.dart';

class HomePage extends StatelessWidget {
  HomePage({super.key});


  Map mainProductCategories = {
    "Burger": ['lib/images/burger_icon.png', '/homePage'],
    "Taco" : ['lib/images/taco_icon.png', '/homePage'],
    "Chicken" : ['lib/images/turkey_icon.png', '/homePage'],
    "Drinks" : ['lib/images/drinks_icon.png', '/introPage'],
  };

  List<Burger> burgerList = [
    Burger(
      imageLocation: 'lib/images/beef_burger_image.png',
      name: "Beef burger",
      price: 5.25,
      discountPercentage: 0,
      description: "Lorem ipsum",
      rating: 4.8,
      size: "Medium",
      subCategory: "Cheesy Mozarrella"
    ),
    Burger(
      imageLocation: 'lib/images/beef_burger_image.png',
      name: "Veg burger",
      price: 3.25,
      discountPercentage: 0,
      description: "Lorem ipsum",
      rating: 4.3,
      size: "Medium",
      subCategory: "Cheesy Mozarrella"
    ),
    Burger(
      imageLocation: 'lib/images/beef_burger_image.png',
      name: "Chicken burger",
      price: 4.53,
      discountPercentage: 0,
      description: "Lorem ipsum",
      rating: 4.9,
      size: "Medium",
      subCategory: "Cheesy Mozarrella"
    ),
    Burger(
      imageLocation: 'lib/images/beef_burger_image.png',
      name: "Beef burger",
      price: 4.51,
      discountPercentage: 10,
      description: "Lorem ipsum.",
      rating: 4.2,
      size: "Medium",
      subCategory: "Cheesy Mozarrella"
    ),
    Burger(
      imageLocation: 'lib/images/beef_burger_image.png',
      name: "Beef burger",
      price: 3.45,
      discountPercentage: 20,
      description: "Lorem ipsum.",
      rating: 4.0,
      size: "Medium",
      subCategory: "Cheesy Mozarrella"
    ),
    Burger(
      imageLocation: 'lib/images/beef_burger_image.png',
      name: "Veg burger",
      price: 4.31,
      discountPercentage: 0,
      description: "Lorem ipsum.",
      rating: 4.0,
      size: "Medium",
      subCategory: "Cheesy Mozarrella"
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(

      // the app bar of the home page
      appBar: AppBar(
        leading: GestureDetector(onTap: () {
          Navigator.pushNamed(context, '/testPage');
        }, child: const Icon(Icons.arrow_left_sharp, color: Colors.black, size: 45,)),
        title: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Container(
            child: Row(
              children: [
                Icon(Icons.location_on, color: primaryButtonColorDark,), 
                const SizedBox(width: 10,),
                Text("Colombo, Sri Lanka", style: TextStyle(color: Colors.grey.shade800, fontSize: 17),)
              ],
            ),
          ),
          const Icon(Icons.notifications, color: Colors.black,),
        ],
      ),
      centerTitle: true,
      elevation: 0,
      backgroundColor: Colors.transparent,
      ),
      //end of the app bar


      body: Column(
        children: [


          // the promo banner stack 
          Stack(
            children: [

              // container with the texts of the promotion banner
              Container(
              margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
              height: 150,
              decoration: BoxDecoration(
                boxShadow:  [BoxShadow(
                  color: Colors.grey.shade400,
                  blurRadius: 10,
                  spreadRadius: 0.1,
                  offset: const Offset(4, 5)
                )],
                borderRadius: BorderRadius.circular(12),
                color: primaryButtonColor,
              ),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  // texts 
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 20),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        const Text("Get Special Discount", style: TextStyle(color: Colors.white, ),),
                        const Text("Up to 80%", style: TextStyle(color: Colors.white, fontSize: 25, fontWeight: FontWeight.w800),),
                        MyButton(buttonText: "Claim voucher", onTap: () {
                          
                        }, borderRadius: 50, 
                        buttonColor: Colors.white,
                        buttonTextSize: 15,
                        buttonTextColor: primaryButtonColor,
                        padx: 20,
                        pady: 10,
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),

            // the other container containing the image over the promo banner
            SizedBox(
              height: 195,
              width: 400,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.end,
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: [
                    Image.asset('lib/images/beef_burger_image.png', height: 195,),
                  ],
                ),
              ),
              // end of the other container containing the image over the promo banner

            ],
          ),
          // the end of the promo banner stack 

          // search bar 
          Padding(
              padding: const EdgeInsets.symmetric(horizontal: 20),
              child: Container(
                height: 54,
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(8),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.grey.shade400,
                      blurRadius: 10,
                      spreadRadius: 0,
                      offset: const Offset(3, 4)
                    )
                  ],
                ),
                child: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: TextField(
                    decoration: InputDecoration(
                      hintText: "find your food...",
                      border: InputBorder.none,
                      prefixIcon: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Image.asset('lib/images/search.png', height: 10, color: Colors.grey,),
                      )
                    ),
                  ),
                ),
              )
            ),
          // end of search bar


          // list view of all the available main food categories 
            SizedBox(
              height: 160,
              child: ListView.builder(itemCount: mainProductCategories.length,scrollDirection: Axis.horizontal,itemBuilder: (context, index) {
                String product = mainProductCategories.keys.elementAt(index);
                List<dynamic> productInfo = mainProductCategories.values.elementAt(index);
              
                return MainCategoryWidget(categoryName: product,imageLocation: productInfo[0],
                );
              },),
            ),
            // end of main product category list view


            // gridview of all the available burgers
            GridView.builder(gridDelegate:const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3), 
              itemCount: burgerList.length,
              itemBuilder: (context, index) {
                final Burger = burgerList[index];
                return Container(
                  padding: EdgeInsets.all(8.0),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(8),
                    boxShadow: [
                      BoxShadow(
                        color: boxShadowColorPrimary,
                        offset: Offset(4, 4),
                        blurRadius: 3,
                      ),
                    ]
                  ),
                  child: Column(
                    children: [
                      Image.asset(Burger.imageLocation),
                      Text(Burger.name),
                      Text(Burger.rating.toString()),
                      Text(Burger.price.toString()),
                    ],
                  ),
                );
              },
            ),
            // end of the grid

        ],
      ),
    );
  }
}

the code for ProductGridView()

import 'package:flutter/material.dart';

class ProductGridView extends StatelessWidget {
  ProductGridView({super.key, required this.productList});

  List productList;

  @override
  Widget build(BuildContext context) {
    return GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),itemCount: productList.length, itemBuilder: (context, index) {
      final Burger = productList[index]; 
      return Container(
        child: Column(
          children: [
            Text(Burger.name),
            Text(Burger.rating.toString()),
            Text(Burger.price.toString())
          ],
        ),
      );
    },);
  }
}

the main():

import 'package:flutter/material.dart';
import 'package:foodie_mobile_application/pages/home_page.dart';
import 'package:foodie_mobile_application/pages/intro_page.dart';
import 'package:foodie_mobile_application/pages/test_page.dart';

void main() => runApp(MaterialApp(
  debugShowCheckedModeBanner: false,
  home: HomePage(),

  routes: {
    '/homePage':(context) => HomePage(),
    '/introPage':(context) => IntroPage(),
    '/testPage':(context) => TestPage(),
  },

  onUnknownRoute: (settings) {
    // Handle unknown routes here
    return MaterialPageRoute(
      builder: (context) => IntroPage(), // Replace with your error page
    );
  },
  // Other MaterialApp configurations
));

I tried to make the GridView.builder in another file and link it to the HomePage() but it didn't work and I even coded the entire project again, still no luck!


Solution

  • Give your GridView.builder height by wrapping it to SizedBox, so that it only expands to its height.