Flutter GridView Tutorial

We will discover how to design a scrollable grid of widgets in a 2D style in this Flutter GridView tutorial series. In order to display groupings of elements, such as photos, cards, or any custom widgets, in an organised grid arrangement, GridViews are frequently used in mobile app development.

Even if you are new to Flutter, you may follow along because we will start with the fundamentals and then graduate to more advanced subjects.

Set up your Flutter project

Create a new Flutter project or open your existing project in your favorite code editor

Create a new Dart file (e.g., grid_view_example.dart) where we’ll write the code for the GridView.

Import the required packages at the top of the Dart file:

import 'package:flutter/material.dart';

Here are the properties of the GridView widget in Flutter, along with explanations for each:

  1. scrollDirection: Determines the scrolling direction of the GridView. It can be set to Axis.vertical for vertical scrolling or Axis.horizontal for horizontal scrolling.
  2. reverse: If set to true, it reverses the scrolling direction. For example, if scrollDirection is set to Axis.vertical, setting reverse to true will cause the GridView to scroll from bottom to top.
  3. controller: This property allows you to supply a ScrollController to control the scrolling behavior of the GridView.
  4. primary: When set to true, it indicates that the GridView is the primary scroll view in the widget tree. It affects how the GridView responds to scrolling gestures.
  5. physics: Defines the scrolling physics for the GridView. You can use different physics classes like ClampingScrollPhysics, BouncingScrollPhysics, or NeverScrollableScrollPhysics to customize the scrolling behavior.
  6. shrinkWrap: If set to true, the GridView will only occupy the space required by its children, allowing it to shrink-wrap its content.
  7. padding: This property adds padding around the GridView.
  8. gridDelegate: This is one of the most important properties for configuring the grid layout. It takes an instance of SliverGridDelegate, which specifies the layout of the grid. Commonly used subclasses are:
    • SliverGridDelegateWithFixedCrossAxisCount: Creates a grid with a fixed number of columns and adjusts the height of rows based on content.
    • SliverGridDelegateWithMaxCrossAxisExtent: Creates a grid with a maximum cross-axis extent, which means you can set the maximum width of columns and the number of columns will be determined accordingly.
    • SliverGridDelegateWithFixedCrossAxisCountAndFixedHeight: Similar to SliverGridDelegateWithFixedCrossAxisCount, but it also fixes the height of each grid item.
  9. children: This property takes a list of widgets that will be displayed in the GridView. Use this when you have a fixed number of items and want to define them explicitly.
  10. gridDelegate: This is an alternative to the children property. Instead of using a fixed list of widgets, you can provide a SliverGridDelegate and use GridView.builder to build the items on-demand based on the delegate’s layout rules.
  11. addAutomaticKeepAlives: Set this to true to enable automatic keeping of state for widgets that are no longer visible within the GridView.
  12. addRepaintBoundaries: If set to true, it creates new repaint boundaries for each child in the GridView. This can be useful for optimizing performance.
  13. addSemanticIndexes: Set this to true if you want to enable automatic semantic indexing for the GridView items.
  14. cacheExtent: Sets the cache extent for the GridView, which controls how many off-screen items are cached. This can affect the performance of scrolling.

In the same file, create a new StatelessWidget called GridViewExample:

class GridViewExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('GridView Example'),
        ),
        body: GridView.builder(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2, // Number of columns in the grid
            crossAxisSpacing: 8.0, // Spacing between columns
            mainAxisSpacing: 8.0, // Spacing between rows
          ),
          itemCount: 10, // Replace this with the number of items you want to display
          itemBuilder: (context, index) {
            // Replace this with the widget you want to display in the grid cell
            return GridTile(
              child: Container(
                color: Colors.teal,
                child: Center(
                  child: Text(
                    'Item ${index + 1}',
                    style: TextStyle(color: Colors.white, fontSize: 20),
                  ),
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

Replace the itemCount and itemBuilder with your actual data. The itemCount should be set to the number of items you want to display, and the itemBuilder should return the widget for each item in the GridView. In this example, we’re using a GridTile widget to display a simple container with a centered text representing the item number.

Save your changes and run the app using flutter run in the terminal or using the run button in your code editor.

You should now see a simple Flutter app with a GridView displaying the items in a 2×2 grid format. You can customize the content of each grid cell and the number of columns by modifying the itemCount and itemBuilder properties in the GridView.builder widget.

There is another example of the gridview

import 'dart:ui';
 
import 'package:flutter/material.dart';
 
void main() => runApp(const MyApp());
 
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
 
  static const String _title = 'Flutter Tutorial';
 
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(title: const Text(_title)),
        body: const MyStatefulWidget(),
      ),
    );
  }
}
 
class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);
 
  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
 
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: GridView(
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
        ),
        primary: false,
        padding: const EdgeInsets.all(20),
        children: <Widget>[
          Container(
            padding: const EdgeInsets.all(5),
            child: const Text("Main Tiles 1"),
            color: Colors.orange[200],
          ),
          Container(
            padding: const EdgeInsets.all(5),
            child: const Text("Main Tiles 2"),
            color: Colors.green[200],
          ),
          Container(
            padding: const EdgeInsets.all(5),
            child: const Text("Main Tiles 3"),
            color: Colors.red[200],
          ),
          Container(
            padding: const EdgeInsets.all(5),
            child: const Text("Main Tiles 4"),
            color: Colors.purple[200],
          ),
          Container(
            padding: const EdgeInsets.all(5),
            child: const Text("Main Tiles 5"),
            color: Colors.blueGrey[200],
          ),
          Container(
            padding: const EdgeInsets.all(5),
            child: const Text("Main Tiles 6"),
            color: Colors.yellow[200],
          ),
        ],
      )
    );
  }
}

Related Posts

Flutter Webview Tutorial

Mastering FlatButton in Flutter

ElevatedButton Tutorial for Flutter

Numeric String Validation in Flutter

Border of Container Widget in Flutter

Flutter Column Explained – Tutorial