Home > Mobile >  Flutter-Renderflex overflow error on each item in GridView.builder()
Flutter-Renderflex overflow error on each item in GridView.builder()

Time:06-05

In my project i need to display a grid of products,2 in each row. For that I am using GridView.builder() as follows :

@override
  Widget build(BuildContext context) {
    return Column(
      children: [
        const Text('New Arrivals'),
        const SizedBox(height: 10),
        Expanded(
          child: Consumer<HomeViewModel>(
            builder: (context, model, child) {
              if (model.state == ViewState.idle) {
                if (model.products.isEmpty) {
                  return const Center(
                    child: CircularProgressIndicator(color: Colors.black),
                  );
                }
                return GridView.builder(
                  shrinkWrap: true,
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 2,
                    mainAxisSpacing: 10,
                    crossAxisSpacing: 10,
                  ),
                  itemBuilder: (context, index) =>
                      ProductItem(product: model.products[index]),
                  itemCount: model.products.length,
                );
              }
              return const Center(
                child: CircularProgressIndicator(color: Colors.black),
              );
            },
          ),
        ),
      ],
    );
  }

However, this is giving an A RenderFlex overflowed by 49 pixels on the bottom. error on each item. The no. of pixels overflowed is different for different item.I have attached the screenshot for reference. What am I doing wrong and how do I fix it? error image

product_item.dart:

class ProductItem extends StatelessWidget {
  const ProductItem({Key? key, required this.product}) : super(key: key);
  final Product product;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 200,
      color: Colors.white,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(
            width: 200,
            height: 150,
            child: Image.network(product.imageUrl!),
          ),
          const SizedBox(height: 13),
          Padding(
            padding: const EdgeInsets.only(left: 8.0),
            child: Text(
              product.category!,
              softWrap: true,
              style: const TextStyle(
                fontSize: 10,
                color: Colors.deepPurple,
                height: 1.5,
                fontWeight: FontWeight.w500,
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(left: 8.0),
            child: Text(
              product.title!,
              softWrap: true,
              style: const TextStyle(
                color: Colors.black54,
                fontSize: 12,
                height: 1.8,
                fontWeight: FontWeight.w500,
              ),
            ),
          ),
          const SizedBox(height: 10),
          Padding(
            padding: const EdgeInsets.only(left: 8.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  '\$ ${product.price!}',
                  style: const TextStyle(
                    color: Colors.black,
                    fontSize: 16,
                    fontWeight: FontWeight.w600,
                    height: 2.4,
                  ),
                ),
                Image.asset('assets/icons/cart_icon.png',
                    width: 40, height: 40),
              ],
            ),
          )
        ],
      ),
    );
  }
}

CodePudding user response:

the problem "should" lie within:

      Padding(
        padding: const EdgeInsets.only(left: 8.0),
        child: Text(
          product.title!,
          softWrap: true,
          style: const TextStyle(
            color: Colors.black54,
            fontSize: 12,
            height: 1.8,
            fontWeight: FontWeight.w500,
          ),
        ),
      ),

try using: AutoSizeText instead of Text

  Padding(
    padding: const EdgeInsets.only(left: 8.0),
    child: AutoSizeText(
      product.title!,
      softWrap: true,
      maxLines: 1,
      style: const TextStyle(
        color: Colors.black54,
        fontSize: 12,
        height: 1.8,
        fontWeight: FontWeight.w500,
      ),
    ),
  ),

CodePudding user response:

Default childAspectRatio is 1 on GridView. The issue arise because it is not fitting inside the square. Item's size is depending on screen width. And width is controlling the height,=> aspect ratio.

You can play with size of grid item using childAspectRatio:width/height. Alternative, you can follow @Maurizio Mancini's answer.

gridDelegate:
    SliverGridDelegateWithFixedCrossAxisCount(
  crossAxisCount: 2,
  childAspectRatio: 3 / 4,//this
),

CodePudding user response:

I have used your code to reproduce the issue. If I understood your needs right, here is the fix:

  • The main problem is related to childAspectRatio.

    return GridView.builder(
      shrinkWrap: true,
      gridDelegate:
        const SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 2,
      mainAxisSpacing: 10,
      crossAxisSpacing: 10,
      childAspectRatio: 0.75,
      ),
      itemBuilder: (context, index) =>
        ProductItem(product: model.products[index]),
      itemCount: model.products.length,
    );
    
  • So you need to set the aspect ratio similar to this to fix the problem.

You can access the working source code through GitHub.

  • Related