How to Fix Overflow Issue in GridView with Custom Item Widget?

Hello everyone,
I’m facing an overflow issue when displaying items inside a GridView in Flutter. I have created a custom Item widget for displaying products in the CategoryScreen, but when I run the app, I get an “A RenderFlex overflowed” error.

Here is my Item widget code:

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:super_mall/core/theme/app_color/app_color_light.dart';

class Item extends StatelessWidget {
  final String path;
  final String title;
  final double price;

  const Item({
    super.key,
    required this.path,
    required this.title,
    required this.price,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(5.r),
      constraints: BoxConstraints(
        minHeight: 220.h,
      ),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(10.r),
        color: AppColorLight.grey1,
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Stack(
            children: [
              SizedBox(
                child: Image.asset(
                  height: 190.w,
                  width: 150.w,
                  path,
                  fit: BoxFit.fitHeight,
                ),
              ),
              Positioned(
                right: 0,
                top: 0,
                child: SvgPicture.asset(
                  'assets/vectors/fav-icon.svg',
                ),
              ),
            ],
          ),
          SizedBox(height: 5.h),
          Text(
            title,
            overflow: TextOverflow.ellipsis,
          ),
          SizedBox(height: 3.h),
          Text('EGP $price'),
        ],
      ),
    );
  }
}

And here is the CategoryScreen where I display the items inside a GridView:

import 'package:flutter/material.dart';
import 'package:super_mall/shared/widget/appbar_back_title.dart';
import 'package:super_mall/shared/widget/item.dart';

class CategoryScreen extends StatelessWidget {
  const CategoryScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppbarBackTitle(),
      body: GridView(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
        ),
        children: [
          Item(path: 'assets/images/example1.png', title: 'Title', price: 100),
          Item(path: 'assets/images/example1.png', title: 'Title', price: 100),
        ],
      ),
    );
  }
}

Issue:

  • When rendering the items inside GridView, I get an overflow error.
  • I suspect that the height of the Item widget is exceeding the available space inside the grid cells.

What I’ve Tried:

  • Wrapping the Item widget inside an Expanded or Flexible widget.
  • Using IntrinsicHeight to adjust the height dynamically.
  • Modifying BoxConstraints but still getting the issue.

What would be the best approach to make sure each grid item fits properly without causing an overflow? Any help would be appreciated!

Wrap Expanded(child: Stack()), remove param height in Image.asset

The sum of your height exceeds what you reserved.

In your code, you are defining the container to be 220 dp in height (don’t know that are those extension methods .h and .w).

Your image has 190 dp height, leaving only 30 dp for the two texts (which clearly is not enough).

Just changing your container size to 283 dp would “fix” it, but it is not a good thing to fix your widgets sizes like this.

Also, make sure your text is allowed to have only 1 line and set the overflow to ellipse or something.

Moreover, your images could use cacheWidth and cacheHeight to minimize RAM usage (if your original images are larger than 150x190xdevicePixelRatio).

What I would do in this case is to set a fixed width only, depending on the available width (you can only get this using LayoutBuilder, don’t go for MediaQuery). Then, you have to decide what is feasible for your layout in portrait, landscape, tablets, foldable phones, etc. 2 images per row works fine on your simulator, but not so much in a foldable phone or in landscape.

Having the width set, the height should be left alone. You know the width, so you can calculate the height of each image using these formulas:

final aspectRatio = originalWidth / originalHeight;
final actualHeight = availableWidth / aspectRatio;

The grid will make each tile the same height automatically.

You can also use the gap package to replace those SizedBox() meant to space your layout. Read the package description for its advantages.