Freeze Panes in Flutter DataGrid (SfDataGrid)
8 Jul 202624 minutes to read
The rows and columns can freeze in view like in Excel. They can be frozen by setting the following properties.
| Property Name | Description |
|---|---|
| frozenRowsCount |
Set the frozen rows count at the top of the SfDataGrid.
|
| footerFrozenRowsCount |
Set the footer frozen rows count at the bottom of the SfDataGrid.
|
| frozenColumnsCount |
Set the frozen columns count on the left side of the SfDataGrid.
|
| footerFrozenColumnsCount |
Set the footer frozen columns on the right side of the SfDataGrid.
|
| frozenPaneElevation | Customize the elevation effect applied to frozen panes. Default value is 5.0. Set to 0.0 to remove elevation and display only the frozen pane line. |
| frozenPaneLineColor | Customize the color of the line displayed at the edge of frozen panes. |
| frozenPaneLineWidth | Customize the width of the line displayed at the edge of frozen panes. |
Freeze columns
The columns can be frozen in view at left and right like Excel by setting the frozenColumnsCount and footerFrozenColumnsCount properties.
The following code example shows how to freeze a column at left using frozenColumnsCount:
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGrid(
source: _orderDataGridSource,
frozenColumnsCount: 1,
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'productId',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Product ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Customer Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'product',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Product',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'orderDate',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
'Order Date',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'quantity',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Quantity',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'city',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'City',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'unitPrice',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Unit Price',
overflow: TextOverflow.ellipsis,
)))
]));
}
The following code example shows how to freeze a column at right using the footerFrozenColumnsCount:
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGrid(
source: _orderDataGridSource,
footerFrozenColumnsCount: 1,
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'productId',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Product ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Customer Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'product',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Product',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'orderDate',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
'Order Date',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'quantity',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Quantity',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'city',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'City',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'unitPrice',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Unit Price',
overflow: TextOverflow.ellipsis,
)))
]));
}
Limitation
-
The
frozenColumnsCountorfooterFrozenColumnsCountshould be less than the total number of columns displayed in the view. For example, If you have 5 columns in the view, you can setfrozenColumnsCountto a maximum value of 4. -
SfDataGrid supports freezing a specific number of columns from the left or right. but not freezing specific columns by name or index.
Freeze rows
The rows can be frozen in view at the top and bottom like in Excel by setting the frozenRowsCount and footerFrozenRowsCount properties.
The following code example shows how to freeze a row at the top using the frozenRowsCount:
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGrid(
source: _orderDataGridSource,
frozenRowsCount: 1,
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'productId',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Product ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Customer Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'product',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Product',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'orderDate',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
'Order Date',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'quantity',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Quantity',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'city',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'City',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'unitPrice',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Unit Price',
overflow: TextOverflow.ellipsis,
)))
]));
}
The following code example shows how to freeze a row at the bottom using the footerFrozenRowsCount:
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGrid(
source: _orderDataGridSource,
footerFrozenRowsCount: 1,
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'productId',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Product ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Customer Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'product',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Product',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'orderDate',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
'Order Date',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'quantity',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Quantity',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'city',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'City',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'unitPrice',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Unit Price',
overflow: TextOverflow.ellipsis,
)))
]));
}
Limitation
-
frozenRowsCountorfooterFrozenRowsCountshould be lesser than the number of rows displayed in the view. For example, If you have 10 rows in view, then you setfrozenRowsCountto a maximum value of 9. -
SfDataGrid has support to freeze the number of rows from top or bottom. There is no support to freeze a specific row.
Note: Header row is frozen by default and works regardless of the
frozenRowsCountproperty.
Appearance
The SfDataGrid allows customizing the appearance of frozen panes through the SfDataGridThemeData property. The DataGrid should be wrapped inside the SfDataGridTheme widget.
The SfDataGridThemeData and SfDataGridTheme classes are available in the syncfusion_flutter_core package. Import the required packages:
import 'package:syncfusion_flutter_core/theme.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';The frozen pane line will be shown only when the frozenPaneElevation property is set to 0. The frozen pane line color and width can be customized using the frozenPaneLineColor and frozenPaneLineWidth properties.
import 'package:syncfusion_flutter_core/theme.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGridTheme(
data: SfDataGridThemeData(
frozenPaneElevation: 0.0,
frozenPaneLineColor: Colors.red,
frozenPaneLineWidth: 1.5,
),
child: SfDataGrid(
source: _orderDataGridSource,
frozenRowsCount: 1,
footerFrozenRowsCount: 1,
frozenColumnsCount: 1,
footerFrozenColumnsCount: 1,
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text('ID', overflow: TextOverflow.ellipsis),
),
),
GridColumn(
columnName: 'productId',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text('Product ID', overflow: TextOverflow.ellipsis),
),
),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text('Customer Name', overflow: TextOverflow.ellipsis),
),
),
GridColumn(
columnName: 'product',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text('Product', overflow: TextOverflow.ellipsis),
),
),
GridColumn(
columnName: 'orderDate',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text('Order Date', overflow: TextOverflow.ellipsis),
),
),
GridColumn(
columnName: 'quantity',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text('Quantity', overflow: TextOverflow.ellipsis),
),
),
GridColumn(
columnName: 'city',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text('City', overflow: TextOverflow.ellipsis),
),
),
GridColumn(
columnName: 'unitPrice',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text('Unit Price', overflow: TextOverflow.ellipsis),
),
),
],
),
),
);
}
Customize frozen pane elevation
The SfDataGrid allows customizing the appearance of the frozen pane elevation by using the frozenPaneElevation property. The default value is 5.0.
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGridTheme(
data: SfDataGridThemeData(frozenPaneElevation: 7.0),
child: SfDataGrid(
source: _orderDataGridSource,
frozenRowsCount: 1,
frozenColumnsCount: 1,
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'productId',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Product ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Customer Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'product',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Product',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'orderDate',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
'Order Date',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'quantity',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Quantity',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'city',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'City',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'unitPrice',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Unit Price',
overflow: TextOverflow.ellipsis,
)))
]),
));
}
Customize frozen pane line appearance
By default, the elevation effect is applied to frozen panes. To hide the elevation and display only the frozen pane line, set the frozenPaneElevation property to 0. Customize the line appearance using the frozenPaneLineColor and frozenPaneLineWidth properties.
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_core/theme.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
@override
Widget build(BuildContext context) {
return Scaffold(
body: SfDataGridTheme(
data: SfDataGridThemeData(
frozenPaneElevation: 0.0,
frozenPaneLineColor: Colors.red,
frozenPaneLineWidth: 1.5),
child: SfDataGrid(
source: _orderDataGridSource,
frozenRowsCount: 1,
frozenColumnsCount: 1,
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'productId',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Product ID',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Customer Name',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'product',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'Product',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'orderDate',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.center,
child: Text(
'Order Date',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'quantity',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Quantity',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'city',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text(
'City',
overflow: TextOverflow.ellipsis,
))),
GridColumn(
columnName: 'unitPrice',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text(
'Unit Price',
overflow: TextOverflow.ellipsis,
)))
]),
));
}
Note:
- Header row behavior — The header row is frozen by default and remains frozen regardless of the
frozenRowsCountproperty. This ensures the column headers remain visible while scrolling through data.- Interaction with other features — Frozen panes work seamlessly with other DataGrid features including sorting, filtering, selection, and styling. Frozen rows and columns maintain their visual separation during these operations.
- Sample applications — Refer to the DataGrid freeze panes sample in the Syncfusion Flutter Examples repository for a complete working implementation.