GridView is a scrollable widget used to display items in a two-dimensional grid, such as galleries, dashboards, product lists, or category menus. In Flutter, it is the grid equivalent of ListView and automatically handles scrolling, layout constraints, and item recycling.
GridView is the appropriate choice when content is arranged in rows and columns and needs to scroll beyond the screen.
For beginners, the simplest way to create a grid is GridView.count.
This constructor allows you to build a grid without dealing with complex delegate classes. It is perfect for static layouts like icon menus or simple dashboards.
GridView.count(
crossAxisCount: 2,
children: [
Container(color: Colors.red),
Container(color: Colors.green),
Container(color: Colors.blue),
Container(color: Colors.orange),
],
);If you just want "two columns and some tiles", this is the fastest and most readable option.
When your grid is based on data from an API, database, or a large list, you should always use GridView.builder.
GridView.builder creates items lazily, meaning widgets are built only when they appear on screen. This is critical for performance.
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1,
),
itemCount: 20,
itemBuilder: (context, index) => Card(
child: Center(child: Text('Item $index')),
),
);Rule of thumb:
GridView.countGridView.builderThis is the most common source of confusion with GridView.
Problem: You add a Container with a fixed height, but GridView ignores it. Tiles look squashed or stretched.
Why this happens: GridView controls the size of its children. Individual height or width values are ignored.
The correct way: You control tile proportions using childAspectRatio.
childAspectRatio is width divided by height.
1.0 → square tiles0.75 → taller tiles1.5 → wider tilesSliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.75,
);If you try to fight GridView with height or width, you will lose. childAspectRatio is the only correct solution.
Dynamic grids usually combine:
GridView.builderNever generate large grids using a for-loop inside children. That approach scales poorly and causes memory issues.
Flutter provides AnimatedGrid for simple insert and remove animations.
It is useful for small to medium grids where visual feedback matters. For large datasets, animations are usually handled at the item level instead.
Just like ListView, GridView inside Column or Row must be wrapped with Expanded.
Without Expanded, Flutter cannot determine the grid’s height and throws a layout error related to unbounded height.
This is one of the most common beginner crashes when working with grids.
Typical beginner issues include:
GridView.builder for small static layouts instead of GridView.count.Container instead of childAspectRatio.GridView inside Column without Expanded.15 min. • Jun 6, 2023
Flutter is known for its seamless UI/UX features and robust design elements. It allowed us to deliver a unique customer experience in the “CA24 Mobile” banking app. This article shares some of the learnings and pain points behind implementing it in this large project.
10 min • Oct 27, 2025
In this article, we’re sharing LeanCode’s 12 practical Flutter and Dart patterns that help you write less boilerplate, make your code cleaner, and catch mistakes earlier. Apply these patterns and you'll find yourself coding faster, communicating more clearly with your teammates, and spending less time debugging issues that the compiler could have caught.