Paging in Flutter DataGrid (SfDataGrid)

26 Jun 202324 minutes to read

The Datagrid interactively supports the manipulation of data using the SfDataPager control. This provides support to load data in segments when dealing with large volumes of data. The SfDataPager can be placed above or under based on the requirement to easily manage data paging.

The Datagrid performs paging of data using the SfDataPager. To enable paging, follow this procedure

NOTE

The SfDataPager.visibleItemsCount property default value is 5.

The following code example illustrates using the SfDataPager with the Datagrid control:

import 'package:intl/intl.dart';

final int _rowsPerPage = 15;

final double _dataPagerHeight = 60.0;

List<OrderInfo> _orders = [];

List<OrderInfo> _paginatedOrders = [];

final OrderInfoDataSource _orderInfoDataSource = OrderInfoDataSource();

@override
Widget build(BuildContext context) {
  return LayoutBuilder(builder: (context, constraint) {
    return Column(children: [
      SizedBox(
          height: constraint.maxHeight - _dataPagerHeight,
          width: constraint.maxWidth,
          child: _buildDataGrid(constraint)),
      Container(
          height: _dataPagerHeight,
          child: SfDataPager(
            delegate: _orderInfoDataSource,
            pageCount: _orders.length / _rowsPerPage,
            direction: Axis.horizontal,
          ))
    ]);
  });
}
Widget _buildDataGrid(BoxConstraints constraint) {
  return SfDataGrid(
      source: _orderInfoDataSource,
      columnWidthMode: ColumnWidthMode.fill,
      columns: <GridColumn>[
        GridColumn(
            columnName: 'orderID',
            label: Container(
                padding: EdgeInsets.symmetric(horizontal: 16.0),
                alignment: Alignment.centerRight,
                child: Text(
                  'Order ID',
                  overflow: TextOverflow.ellipsis,
                ))),
        GridColumn(
            columnName: 'customerID',
            label: Container(
                padding: EdgeInsets.symmetric(horizontal: 16.0),
                alignment: Alignment.centerLeft,
                child: Text(
                  'Customer Name',
                  overflow: TextOverflow.ellipsis,
                ))),
        GridColumn(
            columnName: 'orderDate',
            label: Container(
                padding: EdgeInsets.symmetric(horizontal: 16.0),
                alignment: Alignment.centerRight,
                child: Text(
                  'Order Date',
                  overflow: TextOverflow.ellipsis,
                ))),
        GridColumn(
            columnName: 'freight',
            label: Container(
                padding: EdgeInsets.symmetric(horizontal: 16.0),
                alignment: Alignment.center,
                child: Text(
                  'Freight',
                  overflow: TextOverflow.ellipsis,
                )))
      ]);
}

class OrderInfoDataSource extends DataGridSource {
  OrderInfoDataSource() {
    _paginatedOrders = _orders.getRange(0, 19).toList(growable: false);
    buildPaginatedDataGridRows();
  }

  List<DataGridRow> dataGridRows = [];

  @override
  List<DataGridRow> get rows => dataGridRows;

  @override
  DataGridRowAdapter? buildRow(DataGridRow row) {
    return DataGridRowAdapter(
        cells: row.getCells().map<Widget>((dataGridCell) {
      if (dataGridCell.columnName == 'orderID') {
        return Container(
          padding: EdgeInsets.symmetric(horizontal: 16.0),
          alignment: Alignment.centerRight,
          child: Text(
            dataGridCell.value.toString(),
            overflow: TextOverflow.ellipsis,
          ),
        );
      } else if (dataGridCell.columnName == 'customerID') {
        return Container(
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            alignment: Alignment.centerLeft,
            child: Text(
              dataGridCell.value.toString(),
              overflow: TextOverflow.ellipsis,
            ));
      } else if (dataGridCell.columnName == 'orderDate') {
        return Container(
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            alignment: Alignment.centerRight,
            child: Text(
              DateFormat.yMd().format(dataGridCell.value).toString(),
              overflow: TextOverflow.ellipsis,
            ));
      } else {
        return Container(
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            alignment: Alignment.center,
            child: Text(
              NumberFormat.currency(locale: 'en_US', symbol: '\$')
                  .format(dataGridCell.value)
                  .toString(),
              overflow: TextOverflow.ellipsis,
            ));
      }
    }).toList());
  }

  @override
  Future<bool> handlePageChange(int oldPageIndex, int newPageIndex) async {
    int startIndex = newPageIndex * _rowsPerPage;
    int endIndex = startIndex + _rowsPerPage;
    if (startIndex < _orders.length && endIndex <= _orders.length) {
      _paginatedOrders =
          _orders.getRange(startIndex, endIndex).toList(growable: false);
      buildPaginatedDataGridRows();
      notifyListeners();
    } else {
      _paginatedOrders = [];
    }

    return true;
  }

  void buildPaginatedDataGridRows() {
    dataGridRows = _paginatedOrders.map<DataGridRow>((dataGridRow) {
      return DataGridRow(cells: [
        DataGridCell(columnName: 'orderID', value: dataGridRow.orderID),
        DataGridCell(columnName: 'customerID', value: dataGridRow.customerID),
        DataGridCell(columnName: 'orderDate', value: dataGridRow.orderDate),
        DataGridCell(columnName: 'freight', value: dataGridRow.freight),
      ]);
    }).toList(growable: false);
  }
}

flutter datapager with datagrid

Callbacks

The SfDataPager provides the onPageNavigationStart and onPageNavigationEnd callbacks to listen to the page navigation at the widget level.

Typically, these callbacks are used to show and hide the loading indicator.

@override
Widget build(BuildContext context) {
  return Scaffold(body: LayoutBuilder(builder: (context, constraints) {
    return Row(children: [
      Column(children: [
        SizedBox(
            height: constraints.maxHeight - 60,
            width: constraints.maxWidth,
            child: _buildDataGrid(constraints)),
        Container(
            height: 60,
            width: constraints.maxWidth,
            child: SfDataPager(
                pageCount: _orders.length / _rowsPerPage,
                direction: Axis.horizontal,
                onPageNavigationStart: (int pageIndex) {
                  //You can do your customization
                },
                delegate: _orderInfoDataSource,
                onPageNavigationEnd: (int pageIndex) {
                  //You can do your customization
                }))
      ])
    ]);
  }));
}

Asynchronous data loading

You can load the data asynchronously to the SfDataPager by overriding the handlePageChange method and await the method while loading the data.

You can use onPageNavigationStart and onPageNavigationEnd callbacks to show and hide the loading indicator when navigating between pages.

In the below example, we have set await for 2000ms and displayed the loading indicator until 2000ms.

import 'package:intl/intl.dart';

bool showLoadingIndicator = true;

@override
Widget build(BuildContext context) {
  return Scaffold(body: LayoutBuilder(builder: (context, constraints) {
    return Row(children: [
      Column(children: [
        SizedBox(
            height: constraints.maxHeight - 60,
            width: constraints.maxWidth,
            child: _buildStack(constraints)),
        Container(
            height: 60,
            width: constraints.maxWidth,
            child: SfDataPager(
                pageCount: _orders.length / _rowsPerPage,
                direction: Axis.horizontal,
                onPageNavigationStart: (int pageIndex) {
                  setState(() {
                    showLoadingIndicator = true;
                  });
                },
                delegate: _orderInfoDataSource,
                onPageNavigationEnd: (int pageIndex) {
                  setState(() {
                    showLoadingIndicator = false;
                  });
                }))
      ])
    ]);
  }));
}

Widget _buildStack(BoxConstraints constraints) {
  List<Widget> _getChildren() {
    final List<Widget> stackChildren = [];
    stackChildren.add(_buildDataGrid(constraints));

    if (showLoadingIndicator) {
      stackChildren.add(Container(
          color: Colors.black12,
          width: constraints.maxWidth,
          height: constraints.maxHeight,
          child: Align(
              alignment: Alignment.center,
              child: CircularProgressIndicator(
                strokeWidth: 3,
              ))));
    }

    return stackChildren;
  }

  return Stack(
    children: _getChildren(),
  );
}

class OrderInfoDataSource extends DataGridSource {
  OrderInfoDataSource() {
    _paginatedOrders = _orders.getRange(0, 19).toList(growable: false);
    buildPaginatedDataGridRows();
  }

  List<DataGridRow> dataGridRows = [];

  @override
  List<DataGridRow> get rows => dataGridRows;

  @override
  DataGridRowAdapter? buildRow(DataGridRow row) {
    return DataGridRowAdapter(
        cells: row.getCells().map<Widget>((dataGridCell) {
      if (dataGridCell.columnName == 'orderID') {
        return Container(
          padding: EdgeInsets.symmetric(horizontal: 16.0),
          alignment: Alignment.centerRight,
          child: Text(
            dataGridCell.value.toString(),
            overflow: TextOverflow.ellipsis,
          ),
        );
      } else if (dataGridCell.columnName == 'customerID') {
        return Container(
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            alignment: Alignment.centerLeft,
            child: Text(
              dataGridCell.value.toString(),
              overflow: TextOverflow.ellipsis,
            ));
      } else if (dataGridCell.columnName == 'orderDate') {
        return Container(
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            alignment: Alignment.centerRight,
            child: Text(
              DateFormat.yMd().format(dataGridCell.value).toString(),
              overflow: TextOverflow.ellipsis,
            ));
      } else {
        return Container(
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            alignment: Alignment.center,
            child: Text(
              NumberFormat.currency(locale: 'en_US', symbol: '\$')
                  .format(dataGridCell.value)
                  .toString(),
              overflow: TextOverflow.ellipsis,
            ));
      }
    }).toList());
  }

  @override
  Future<bool> handlePageChange(int oldPageIndex, int newPageIndex) async {
    int startIndex = newPageIndex * _rowsPerPage;
    int endIndex = startIndex + _rowsPerPage;
    if (startIndex < _orders.length && endIndex <= _orders.length) {
      await Future.delayed(Duration(milliseconds: 2000));
      _paginatedOrders =
          _orders.getRange(startIndex, endIndex).toList(growable: false);
      buildPaginatedDataGridRows();
      notifyListeners();
    } else {
      _paginatedOrders = [];
    }

    return true;
  }

  void buildPaginatedDataGridRows() {
    dataGridRows = _paginatedOrders.map<DataGridRow>((dataGridRow) {
      return DataGridRow(cells: [
        DataGridCell(columnName: 'orderID', value: dataGridRow.orderID),
        DataGridCell(columnName: 'customerID', value: dataGridRow.customerID),
        DataGridCell(columnName: 'orderDate', value: dataGridRow.orderDate),
        DataGridCell(columnName: 'freight', value: dataGridRow.freight),
      ]);
    }).toList(growable: false);
  }
}

flutter datapager with asynchronous loading

NOTE
Download demo application from GitHub.

Programmatic page navigation

The SfDataPager provides the support to navigate between the pages programmatically using a controller with the following options.

The following code example shows how to navigate the previous page programmatically,

DataPagerController _controller = DataPagerController();

@override
Widget build(BuildContext context) {
  return Scaffold(body: LayoutBuilder(builder: (context, constraint) {
    return Column(children: [
      MaterialButton(
        onPressed: () {
          _controller.previousPage();
        },
        child: Text('Move Previous page'),
      ),
      SizedBox(
          height: constraint.maxHeight - 120,
          width: constraint.maxWidth,
          child: _buildDataGrid(constraint)),
      Container(
          height: 60,
          child: Align(
              alignment: Alignment.center,
              child: SfDataPager(
                delegate: _orderInfoDataSource,
                initialPageIndex: 2,
                controller: _controller,
                pageCount: _orders.length / _rowsPerPage,
                direction: Axis.horizontal,
              )))
    ]);
  }));
}

Show dropdown button to choose rows per page

Show the dropdown button option to select a different number of rows per page by defining the onRowPerPageChanged callback. If it is null, no option will be provided to select a different number of rows per page.

Use the availableRowsPerPage property to define the list of numbers to be displayed in the drop-down. The default value of the availableRowsPerPage property is [10,15,20].

NOTE
You can view dropdown button option by horizontally scrolling the DataPager. The dropdown button option is not supported, if the direction is vertical.

int _rowsPerPage=10;
  List<Employee> employees = <Employee>[];
  late EmployeeDataSource employeeDataSource;
  double datapagerHeight = 70.0;

  @override
  void initState() {
    super.initState();
    employees = getEmployeeData();
    employeeDataSource = EmployeeDataSource(employeeData: employees);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Syncfusion Flutter DataGrid'),
        ),
        body: LayoutBuilder(
            builder: (BuildContext context, BoxConstraints constraints) {
          return Column(
            children: [
              Container(
                height: constraints.maxHeight - datapagerHeight,
                child: SfDataGrid(
                    source: employeeDataSource,
                    columnWidthMode: ColumnWidthMode.fill,
                    columns: _column),
              ),
              Container(
                  height: datapagerHeight,
                  child: SfDataPager(
                    delegate: employeeDataSource,
                    availableRowsPerPage: [10, 20, 30],
                    onRowsPerPageChanged: (int? rowsPerPage) {
                      setState(() {
                        _rowsPerPage = rowsPerPage!;
                        employeeDataSource.updateDataGriDataSource();
                      });
                    },
                    pageCount:
                        ((employees.length / _rowsPerPage).ceil()).toDouble(),
                  )),
            ],
          );
        }));
  }

  class EmployeeDataSource extends DataGridSource {
  /// Creates the employee data source class with required details.
  EmployeeDataSource({required List<Employee> employeeData}) {
    _employeeData = employeeData;
    _paginatedRows = employeeData;
    buildDataGridRow();
  }

  void buildDataGridRow() {
    _employeeDataGridRows = _paginatedRows
        .map<DataGridRow>((e) => DataGridRow(cells: [
              DataGridCell<int>(columnName: 'id', value: e.id),
              DataGridCell<String>(columnName: 'name', value: e.name),
              DataGridCell<String>(
                  columnName: 'designation', value: e.designation),
              DataGridCell<int>(columnName: 'salary', value: e.salary),
            ]))
        .toList();
  }

  List<DataGridRow> _employeeDataGridRows = [];
  List<Employee> _paginatedRows = [];
  List<Employee> _employeeData = [];

  @override
  List<DataGridRow> get rows => _employeeDataGridRows;

  @override
  DataGridRowAdapter buildRow(DataGridRow row) {
    return DataGridRowAdapter(
        cells: row.getCells().map<Widget>((e) {
      return Container(
        alignment: Alignment.center,
        padding: EdgeInsets.all(8.0),
        child: Text(e.value.toString()),
      );
    }).toList());
  }

  @override
  Future<bool> handlePageChange(int oldPageIndex, int newPageIndex) {
    final int _startIndex = newPageIndex * _rowsPerPage;
    int _endIndex = _startIndex + _rowsPerPage;
    if (_endIndex > _employeeData.length) {
      _endIndex = _employeeData.length;
    }

    /// Get a particular range from the sorted collection.
    if (_startIndex < _employeeData.length &&
        _endIndex <= _employeeData.length) {
      _paginatedRows = _employeeData.getRange(_startIndex, _endIndex).toList();
    } else {
      _paginatedRows = <Employee>[];
    }
    buildDataGridRow();
    notifyListeners();
    return Future<bool>.value(true);
  }

  void updateDataGriDataSource() {
    notifyListeners();
  }
  }

flutter datapager with rowsperpage

Orientation

SfDataPager allows you to arrange the child elements either horizontally or vertically. This can be achieved by using the direction Property. direction is an Enum type.

Enum Description
horizontal This is the default enum value for direction. Arranges all the navigation buttons and numeric buttons horizontally.

flutter datapager in horizontal direction

vertical Arranges all the navigation buttons and numeric buttons vertically by setting Axis.vertical to direction property.

flutter datapager in vertical direction

Appearance

SfDataPager allows customizing the appearance of the data pager using the SfDataPagerThemeData in SfDataPagerTheme. The SfDataPager should be wrapped inside the SfDataPagerTheme.

Import the following class from the syncfusion_flutter_core package.

import 'package:syncfusion_flutter_core/theme.dart';

The following code example illustrates using SfDataPagerThemeData with the data pager control

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: SfDataPagerTheme(
      data: SfDataPagerThemeData(
        itemColor: Colors.white,
        selectedItemColor: Colors.lightGreen,
        itemBorderRadius: BorderRadius.circular(5),
        backgroundColor: Colors.teal,
      ),
      child: SfDataPager(
        delegate: _orderInfoDataSource,
        pageCount: _orders.length / _rowsPerPage,
        direction: Axis.horizontal,
      ),
    ),
  );
}

flutter datapager with customization

Set the padding between page items

The padding between the page items including navigation page items such as first, last, previous and next can be changed by using the itemPadding property.

@override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Syncfusion Flutter DataGrid'),
        ),
        body: SfDataPager(
            itemPadding: EdgeInsets.all(8.0),
            pageCount: 5,
            delegate: employeeDataSource,
          ),
        );
  }

NOTE

The default value of SfDataPager.itemPadding is 5.0.

Set the height and width of the page items

The default width and height of the page items are 50 and 50, respectively. For changing page number items size, use the itemWidth and itemHeight properties; for changing navigation items size such as first, last, previous, and next, use the navigationItemHeight and navigationItemWidth properties.

@override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Syncfusion Flutter DataGrid'),
        ),
        body: Center(
            child: SfDataPagerTheme(
          data: SfDataPagerThemeData(
            itemBorderWidth: 0.5,
            itemBorderColor: Colors.grey.shade400,
            itemBorderRadius: BorderRadius.circular(5),
          ),
          child: SfDataPager(
            pageCount: 5,
            visibleItemsCount: 2,
            itemWidth: 70,
            itemHeight: 55,
            navigationItemWidth: 70,
            navigationItemHeight: 55,
            delegate: employeeDataSource,
          ),
        )));
  }

flutter datapager with page button resizing

Hide certain navigation page items

To hide certain navigation page items, use the following properties:

NOTE

Default value of all properties is true.

@override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Syncfusion Flutter DataGrid'),
        ),
        body: SfDataPagerTheme(
          data: SfDataPagerThemeData(
              itemBorderWidth: 0.5,
              itemBorderColor: Colors.grey.shade400,
              itemBorderRadius: BorderRadius.circular(5),
              selectedItemColor: Colors.indigo.shade500),
          child: SfDataPager(
            firstPageItemVisible: false,
            lastPageItemVisible: false,
            pageCount: 5,
            visibleItemsCount: 3,
            navigationItemWidth: 100,
            delegate: employeeDataSource,
            pageItemBuilder: (String itemName) {
              if (itemName == 'Next') {
                return Center(
                  child: Text('Next'),
                );
              }
              if (itemName == 'Previous') {
                return Center(
                  child: Text('Previous'),
                );
              }
            },
            itemPadding: EdgeInsets.all(8.0),
          ),
        ));
  }

flutter datapager with page button resizing

Change the number of visible items (buttons) in the view

You can change the number of visible items i.e. page buttons in view by using the SfDataPager.visibleItemsCount.

@override
Widget build(BuildContext context) {
  return Scaffold(
      appBar: AppBar(
        title: Text('Flutter DataGrid Sample'),
      ),
      body: LayoutBuilder(builder: (context, constraint) {
        return Column(
          children: [
            SizedBox(
                height: constraint.maxHeight - _dataPagerHeight,
                width: constraint.maxWidth,
                child: _buildDataGrid(constraint)),
            Container(
              height: _dataPagerHeight,
              child: SfDataPager(
                visibleItemsCount: 1,
                delegate: _orderInfoDataSource,
                pageCount: _orders.length / _rowsPerPage,
                direction: Axis.horizontal,
              ),
            )
          ],
        );
      }));
}

Load any widget in the page button

Load any widget to the page button by using the SfDataPager.pageItemBuilder.

@override
Widget build(BuildContext context) {
  return Scaffold(
      appBar: AppBar(
        title: Text('Flutter DataGrid Sample'),
      ),
      body: LayoutBuilder(builder: (context, constraint) {
        return Column(children: [
          SizedBox(
              height: constraint.maxHeight - _dataPagerHeight,
              width: constraint.maxWidth,
              child: _buildDataGrid(constraint)),
          Container(
              height: _dataPagerHeight,
              child: SfDataPagerTheme(
                  data: SfDataPagerThemeData(
                    itemBorderColor: Colors.blue,
                    itemBorderWidth: 1,
                    backgroundColor: Colors.transparent,
                    itemBorderRadius: BorderRadius.circular(0),
                  ),
                  child: SfDataPager(
                    pageItemBuilder: (String value) {
                      return Container(
                          child: Text(
                        value,
                        style: TextStyle(
                            fontSize: 10, fontWeight: FontWeight.w700),
                      ));
                    },
                    delegate: _orderInfoDataSource,
                    pageCount: _orders.length / _rowsPerPage,
                    direction: Axis.horizontal,
                  )))
        ]);
      }));
}

Sort all the rows instead of rows available on a page

By default, the rows on a page are sorted. To sort all the rows available for paging, do not override the handlePageChange method in the DataGridSource class. The DataGrid will automatically split the rows required for each page based on the SfDataPager.pageCount, i.e. the divided value of the DataGridRows.rows and SfDataPager.pageCount.

If you want to specifically maintain the rows required for a page, you can use the SfDataGrid.rowsPerPage property. However, make sure that you do not override the handlePageChange method in the DataGridSource class at the sample level.

final int _rowsPerPage = 15;

final double _dataPagerHeight = 60.0;

List<OrderInfo> _orders = [];

@override
Widget build(BuildContext context) {
  return Scaffold(body: LayoutBuilder(builder: (context, constraint) {
    return Column(children: [
      SizedBox(
          height: constraint.maxHeight - _dataPagerHeight,
          width: constraint.maxWidth,
          child: _buildDataGrid(constraint)),
      Container(
          height: _dataPagerHeight,
          child: SfDataPager(
            delegate: _orderInfoDataSource,
            pageCount: (_orders.length / _rowsPerPage).ceil().toDouble(),
            direction: Axis.horizontal,
          ))
    ]);
  }));
}

Widget _buildDataGrid(BoxConstraints constraint) {
  return SfDataGrid(
      source: _orderInfoDataSource,
      columnWidthMode: ColumnWidthMode.fill,
      rowsPerPage: _rowsPerPage,
      allowSorting: true,
      columns: <GridColumn>[
        GridColumn(
            columnName: 'orderID',
            label: Container(
                padding: EdgeInsets.symmetric(horizontal: 16.0),
                alignment: Alignment.centerRight,
                child: Text(
                  'Order ID',
                  overflow: TextOverflow.ellipsis,
                ))),
        GridColumn(
            columnName: 'customerID',
            label: Container(
                padding: EdgeInsets.symmetric(horizontal: 16.0),
                alignment: Alignment.centerLeft,
                child: Text(
                  'Customer Name',
                  overflow: TextOverflow.ellipsis,
                ))),
        GridColumn(
            columnName: 'orderDate',
            label: Container(
                padding: EdgeInsets.symmetric(horizontal: 16.0),
                alignment: Alignment.centerRight,
                child: Text(
                  'Order Date',
                  overflow: TextOverflow.ellipsis,
                ))),
        GridColumn(
            columnName: 'freight',
            label: Container(
                padding: EdgeInsets.symmetric(horizontal: 16.0),
                alignment: Alignment.center,
                child: Text(
                  'Freight',
                  overflow: TextOverflow.ellipsis,
                )))
      ]);
}

class OrderInfoDataSource extends DataGridSource {
  OrderInfoDataSource() {
    buildDataGridRows();
  }

  List<DataGridRow> dataGridRows = [];

  @override
  List<DataGridRow> get rows => dataGridRows;

  @override
  DataGridRowAdapter? buildRow(DataGridRow row) {
    return DataGridRowAdapter(
        cells: row.getCells().map<Widget>((dataGridCell) {
      if (dataGridCell.columnName == 'orderID') {
        return Container(
          padding: EdgeInsets.symmetric(horizontal: 16.0),
          alignment: Alignment.centerRight,
          child: Text(
            dataGridCell.value.toString(),
            overflow: TextOverflow.ellipsis,
          ),
        );
      } else if (dataGridCell.columnName == 'customerID') {
        return Container(
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            alignment: Alignment.centerLeft,
            child: Text(
              dataGridCell.value.toString(),
              overflow: TextOverflow.ellipsis,
            ));
      } else if (dataGridCell.columnName == 'orderDate') {
        return Container(
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            alignment: Alignment.centerRight,
            child: Text(
              DateFormat.yMd().format(dataGridCell.value).toString(),
              overflow: TextOverflow.ellipsis,
            ));
      } else {
        return Container(
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            alignment: Alignment.center,
            child: Text(
              NumberFormat.currency(locale: 'en_US', symbol: '\$')
                  .format(dataGridCell.value)
                  .toString(),
              overflow: TextOverflow.ellipsis,
            ));
      }
    }).toList());
  }

  void buildDataGridRows() {
    dataGridRows = _orders.map<DataGridRow>((dataGridRow) {
      return DataGridRow(cells: [
        DataGridCell(columnName: 'orderID', value: dataGridRow.orderID),
        DataGridCell(columnName: 'customerID', value: dataGridRow.customerID),
        DataGridCell(columnName: 'orderDate', value: dataGridRow.orderDate),
        DataGridCell(columnName: 'freight', value: dataGridRow.freight),
      ]);
    }).toList(growable: false);
  }
}

sorting applied for all the rows in flutter datagrid paging