When developing applications in Flutter, you may encounter situations where you need to display a list of items in grid form. You can use the GridView class in Flutter to display data in grid format — that is, with rows and columns.

Using a GridView is the best way to combine row and column classes and create a scrollable grid list. A common use case is to display a list of photos, such as in Google’s and Apple’s native Photos apps.

In this tutorial, we will demonstrate how to implement GridView in your Flutter application. We’ll also look at some practical examples to show you what the GridView can do.

We will cover the following in detail.

  • What is a GridView?
  • The GridView properties
  • Displays a list with a fixed number of items
  • Display a long list in a GridView
  • Build a reactive GridView

If you’re a visual learner, check out this quick video tutorial.

What is a GridView?

In Flutter, the GridView is a widget that displays a list of items as a 2D array. Simply put, items are presented in table form.

Unlike a normal list, the GridView displays items in only one direction; it displays items in both horizontal and vertical directions. The following figure shows how a GridView differs from a regular list in the Flutter application.

Here is the minimal code to get the GridView up and running.

GridView(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3,
  ),
  children: [
    Image.network('https://picsum.photos/250?image=1'),
    Image.network('https://picsum.photos/250?image=2'),
    Image.network('https://picsum.photos/250?image=3'),
    Image.network('https://picsum.photos/250?image=4'),
  ],
)

Copy the code

A gridDelegate is a property that controls how items in a list are displayed. In our case, it is endowed with SliverGridDelegateWithFixedCrossAxisCount (), crossAxisCount set to 3. This means we want to display three items horizontally if the scroll direction is vertical, and three items vertically if the scroll direction is horizontal. The default scrolling direction for any list is only vertical, so items are displayed horizontally.

Children refers to the list of items given here. It accepts a list of any widgets, so you can display anything you want on the screen.

Here is the output.

Here’s how the code is translated into the user interface.

The GridView properties

Let’s take a look at some properties of the GridView.

crossAxisSpacing

Setting a value for this property allows you to place a space between items on the horizontal axis. This means that if the scrolling direction is vertical, space will appear horizontally.

GridView(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 3, 
      crossAxisSpacing: 16),
  children: [
    Image.network('https://picsum.photos/250?image=1'),
    Image.network('https://picsum.photos/250?image=2'),
    Image.network('https://picsum.photos/250?image=3'),
)

Copy the code

mainAxisSpacing

The main axis is the axis on which the list scrolls. The space between items in the scrolling direction is given using the mainAxisSpacing attribute.

GridView(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 3, 
      mainAxisSpacing: 16),
  children: [
    Image.network('https://picsum.photos/250?image=1'),
    Image.network('https://picsum.photos/250?image=2'),
    Image.network('https://picsum.photos/250?image=3'),
)

Copy the code

scrollDirection

When the GridView is displayed in landscape mode, you may want to change the scrolling direction. You can do this by setting scrollDirection to Axis. Horizontal.

GridView(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3,
  ),
  scrollDirection: Axis.horizontal,
  children: [
    ...
  ],
)

Copy the code

physics

This property allows you to set the scrolling behavior of the list. You probably don’t want the list to scroll at all. Let’s say you want to display a collage of images. You can use the physics value is set to NeverScrollableScrollPhysics () to disable the scroll. By default, Android uses ClampingScrollPhysics() and iOS uses BouncingScrollPhysics(), which looks something like this.

shrinkWrap

Set the shrinkWrap value to true so that the GridView takes up only as much space as it needs to fill items in the scrolling direction. This defaults to false and preserves the entire screen even if the item is not in the list.

/////shrinkWrap: false,
Column(
  children: [
    Expanded(
      child: GridView(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
        ),
        shrinkWrap: false,
        children: [... ],
      ),
    ),
    ElevatedButton(onPressed: () {}, child: Text('Close'))
  ],
)
/////shrinkWrap: true,
Column(
  children: [
    GridView(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 3,
      ),
      shrinkWrap: true,
      children: [...],
    ),
    ElevatedButton(onPressed: () {}, child: Text('Close'))
  ],
)

Copy the code

When shrinkWrap is false, we need to pack the GridView inside the Expanded Widget so that it takes up all available space. Otherwise, it will make an error.

Displays a list of items with a fixed number

Flutter has a constructor that displays only a few items in the GridView, called gridView.count (). This constructor enables you to create a GridView with a fixed number of items. It also simplifies the way to specify the number of items on the horizontal axis.

The sample code looks like this.

GridView.count(
  crossAxisCount: 3,
  children: [
    ...
  ],
)

Copy the code

The number of items to display on the cross axis is assigned to the crossAxisCount attribute. If you look closely, you’ll see that we no longer need SliverGridDelegateWith FixedCrossAxisCount().

Gridview.count () can be used to create such a keyboard user interface.

Here is the code for the above design.

GridView.count(
  crossAxisCount: 3,
  shrinkWrap: true,
  padding: EdgeInsets.only(left: 24, right: 24),
  children: [
    DialKey(
      number: '1',
      letters: '',
    ),
...
  ],
)

Copy the code

The shrinkWrap property is set to true, which causes the GridView to free up some space on the screen.

DialKey() is a custom widget that displays a single key. It looks something like this.

// DialKey widget class DialKey extends StatelessWidget { final String number; final String letters; DialKey({this.number, this.letters}); @override Widget build(BuildContext context) { return Center( child: Container( width: 80, height: 80, child: FloatingActionButton(onPressed: () {}, backgroundColor: color.grey.withopacity (0.5), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( '$number', style: TextStyle( color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold), ), Text( '$letters', style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold), ) ], ), ), ), ); }}Copy the code

Display a long list in a GridView

To display a long list or an infinite number of items that might come from the database, you need the GridView.Builder () constructor.

Here is the sample code.

GridView.builder(
  itemCount: 100,
  itemBuilder: (context, index) => ItemTile(index),
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2,
  ),
)

Copy the code

ItemCount represents the number of items. This helps the GridView estimate the maximum scrolling range.

The itemBuilder creates the given widget based on the current index.

Let’s try to build a list of such products.

Here’s the code.

GridView.builder( itemCount: 100, itemBuilder: (context, index) => ItemTile(index), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, childAspectRatio: 2, ), ) class ItemTile extends StatelessWidget { final int itemNo; const ItemTile( this.itemNo, ); @override Widget build(BuildContext context) { final Color color = Colors.primaries[itemNo % Colors.primaries.length]; Return Padding(Padding: const EdgeInsets. All (8.0), child: ListTile(tileColor: color.withopacity (0.3), onTap: () {}, leading: Container(width: 50, height: 30, color: color. WithOpacity (0.5), child: Placeholder(color: Placeholder) color, ), ), title: Text( 'Product $itemNo', key: Key('text_$itemNo'), ), ), ); }}Copy the code

One thing to notice in the code above is the childAspectRatio property. This can be used to adjust the height of the project, as shown below.

Build a reactive GridView

With the release of Flutter 2.0, you can now develop applications for the web and desktop as well as mobile. When building cross-platform applications, make sure you cater to web users by creating the best possible user experience. In this case, displaying more items on the grid can greatly improve the user experience of web users when the grid is displayed on a large screen.

Let’s modify the previous code to show more items on the horizontal axis when displayed on the large screen.

//Before
GridView.builder(
  itemCount: 100,
  itemBuilder: (context, index) => ItemTile(index),
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2,
    childAspectRatio: 2,
  ),
)
//After
LayoutBuilder(builder: (context, constraints) {
  return GridView.builder(
    itemCount: 100,
    itemBuilder: (context, index) => ItemTile(index),
    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: constraints.maxWidth > 700 ? 4 : 1,
      childAspectRatio: 5,
    ),
  );
})

Copy the code

Wrap the GridView around the LayoutBuilder. LayoutBuilder provides constraints, which can be used to determine the width and height. With these constraints, we can build various user interfaces.

For our example, whenever the screen resolution is 700 or more wide, we display four items on the horizontal axis.

Here is the output.

conclusion

If you’ve made it this far, you should have all the necessary skills and basics to create complex and attractive grid lists using GridView in Flutter.

The full code for this example can be found on GitHub.

The postHow to create a grid list in Flutter using GridViewappeared first onLogRocket Blog.