skills/syncfusion-flutter-datagrid/references/grouping.md

9.1 KiB

Grouping — Flutter DataGrid

Overview

SfDataGrid supports grouping rows by one or more column values. Groups can be expanded/collapsed, customized, and managed programmatically. Use DataGridSource.addColumnGroup to define grouping columns, and override DataGridSource.buildGroupCaptionCellWidget to render the group caption row.


Basic Grouping

Call addColumnGroup in initState to group rows by a column:

@override
void initState() {
  super.initState();
  employeeDataSource = EmployeeDataSource(employeeData: employees);
  employeeDataSource.addColumnGroup(
    ColumnGroup(name: 'City', sortGroupRows: true),
  );
}
SfDataGrid(
  source: employeeDataSource,
  columnWidthMode: ColumnWidthMode.fill,
  columns: [
    GridColumn(
      columnName: 'id',
      label: Container(
        padding: EdgeInsets.all(16),
        alignment: Alignment.center,
        child: Text('ID'),
      ),
    ),
    GridColumn(
      columnName: 'name',
      label: Container(
        padding: EdgeInsets.all(8),
        alignment: Alignment.center,
        child: Text('Name'),
      ),
    ),
    GridColumn(
      columnName: 'city',
      label: Container(
        padding: EdgeInsets.all(8),
        alignment: Alignment.center,
        child: Text('City'),
      ),
    ),
    GridColumn(
      columnName: 'salary',
      label: Container(
        padding: EdgeInsets.all(8),
        alignment: Alignment.center,
        child: Text('Salary'),
      ),
    ),
  ],
)

Override buildGroupCaptionCellWidget in DataGridSource:

@override
Widget? buildGroupCaptionCellWidget(
    RowColumnIndex rowColumnIndex, String summaryValue) {
  return Container(
      padding: EdgeInsets.symmetric(horizontal: 12, vertical: 15),
      child: Text(summaryValue));
}

Note: ColumnGroup.name must exactly match the GridColumn.columnName.


Multi-Level Grouping

Add multiple ColumnGroup entries — the first added becomes the outermost (primary) group:

employeeDataSource.addColumnGroup(
  ColumnGroup(name: 'City', sortGroupRows: true),
);
employeeDataSource.addColumnGroup(
  ColumnGroup(name: 'Designation', sortGroupRows: true),
);

Removing and Clearing Groups

// Remove a specific group
final group = employeeDataSource.groupedColumns
    .firstWhereOrNull((g) => g.name == 'City');
if (group != null) {
  employeeDataSource.removeColumnGroup(group);
}

// Clear all groups
employeeDataSource.clearColumnGroups();

Expand and Collapse

Enable expand/collapse UI with allowExpandCollapseGroup:

SfDataGrid(
  source: employeeDataSource,
  allowExpandCollapseGroup: true,
  autoExpandGroups: false,   // collapse all groups on initial load
  columns: columns,
)
Property Type Default Description
allowExpandCollapseGroup bool false Show expand/collapse icons on group caption rows
autoExpandGroups bool true Expand all groups on initial load; set false to collapse

Expand/Collapse Callbacks

SfDataGrid(
  source: employeeDataSource,
  allowExpandCollapseGroup: true,
  columns: columns,
  groupExpanding: (DataGridGroupChangingDetails group) {
    // return false to cancel expanding
    return true;
  },
  groupExpanded: (DataGridGroupChangedDetails group) {
    print('Group expanded: ${group.key}');
  },
  groupCollapsing: (DataGridGroupChangingDetails group) {
    // return false to cancel collapsing
    return true;
  },
  groupCollapsed: (DataGridGroupChangedDetails group) {
    print('Group collapsed: ${group.key}');
  },
)

Programmatic Expand/Collapse

Use DataGridController to expand or collapse groups programmatically:

final DataGridController _dataGridController = DataGridController();

SfDataGrid(
  source: employeeDataSource,
  controller: _dataGridController,
  allowExpandCollapseGroup: true,
  columns: columns,
)

// Expand/collapse all
_dataGridController.expandAllGroup();
_dataGridController.collapseAllGroup();

// Expand/collapse by nesting level (1-based)
_dataGridController.expandGroupsAtLevel(1);
_dataGridController.collapseGroupsAtLevel(2);

Custom Group Caption Row

Override buildGroupCaptionCellWidget in your DataGridSource to return a custom widget for the caption row:

class EmployeeDataSource extends DataGridSource {
  @override
  Widget? buildGroupCaptionCellWidget(
      RowColumnIndex rowColumnIndex, String summaryValue) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 12, vertical: 15),
      child: Text(summaryValue),
    );
  }
}

Caption Title Format

Customize the caption display string using groupCaptionTitleFormat:

SfDataGrid(
  source: employeeDataSource,
  groupCaptionTitleFormat: '{ColumnName} : {Key} - {ItemsCount} Items',
  columns: columns,
)

Available placeholders:

Placeholder Description
{ColumnName} The column being grouped
{Key} The group key value
{ItemsCount} Number of items in the group

Default format: '{ColumnName} : {Key} - {ItemsCount} Items'


Custom Grouping Logic

Override performGrouping in DataGridSource to define a custom group key:

class EmployeeDataSource extends DataGridSource {
  @override
  String? performGrouping(String columnName, DataGridRow row) {
    if (columnName == 'salary') {
      final salary = row
          .getCells()
          .firstWhere((cell) => cell.columnName == 'salary')
          .value as int;
      if (salary < 10000) return 'Low';
      if (salary < 20000) return 'Medium';
      return 'High';
    }
    return super.performGrouping(columnName, row);
  }
}

Indent Column Customization

The indent column is the left-side column used to show group hierarchy depth. Customize it via SfDataGridThemeData:

SfDataGridTheme(
  data: SfDataGridThemeData(
    indentColumnWidth: 60.0,      // default: 40.0
    indentColumnColor: Colors.teal,
  ),
  child: SfDataGrid(
    source: employeeDataSource,
    allowExpandCollapseGroup: true,
    columns: columns,
  ),
)

Expander Icon Customization

SfDataGridTheme(
  data: SfDataGridThemeData(
    groupExpanderIcon: Icon(Icons.arrow_drop_down, color: Colors.blue),
  ),
  child: SfDataGrid(
    source: employeeDataSource,
    allowExpandCollapseGroup: true,
    columns: columns,
  ),
)

Key Property Reference

SfDataGrid Properties

Property Type Default Description
allowExpandCollapseGroup bool false Enable expand/collapse UI on group caption rows
autoExpandGroups bool true Expand all groups on initial load
groupCaptionTitleFormat String '{ColumnName} : {Key} - {ItemsCount} Items' Format string for group caption rows
groupExpanding bool? Function(DataGridGroup)? null Callback before expanding; return false to cancel
groupExpanded void Function(DataGridGroup)? null Callback after expanding
groupCollapsing bool? Function(DataGridGroup)? null Callback before collapsing; return false to cancel
groupCollapsed void Function(DataGridGroup)? null Callback after collapsing

DataGridSource Methods

Method Description
addColumnGroup(ColumnGroup) Add a grouping column
removeColumnGroup(ColumnGroup) Remove a specific grouping column
clearColumnGroups() Remove all grouping columns
performGrouping(columnName, row) Override to return custom group key
buildGroupCaptionCellWidget(rowColumnIndex, summaryValue) Override to return custom caption widget

DataGridController Methods

Method Description
expandAllGroup() Expand all groups
collapseAllGroup() Collapse all groups
expandGroupsAtLevel(int level) Expand groups at a specific nesting level (1-based)
collapseGroupsAtLevel(int level) Collapse groups at a specific nesting level (1-based)

ColumnGroup Properties

Property Type Description
name String Column name to group by (must match GridColumn.columnName)
sortGroupRows bool Whether to sort rows within the group

Important Notes

  • CRUD operations (add/remove rows) reset the expand/collapse state based on the autoExpandGroups value.
  • Set SfDataGrid.columns as an instance variable (not inline) to prevent unnecessary grid refresh when grouping is applied.
  • Multi-level grouping: first addColumnGroup call = outermost group.

TOC