PaginatedDataTable class
A table that follows the Material 2 design specification, using multiple pages to display data.
A paginated data table shows rowsPerPage rows of data per page and provides controls for showing other pages.
Data is read lazily from a DataTableSource. The widget is presented as a Card.
If the key is a PageStorageKey, the initialFirstRowIndex is persisted to PageStorage.
This sample shows how to display a DataTable with three columns: name, age, and role. The columns are defined by three DataColumn objects. The table contains three rows of data for three example users, the data for which is defined by three DataRow objects.
To see it in action, copy and run this code snippet on DartPad.
import 'package:material_ui/material_ui.dart';
/// Flutter code sample for [PaginatedDataTable].
class MyDataSource extends DataTableSource {
@override
int get rowCount => 3;
@override
DataRow? getRow(int index) {
switch (index) {
case 0:
return const DataRow(
cells: <DataCell>[
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
],
);
case 1:
return const DataRow(
cells: <DataCell>[
DataCell(Text('Janine')),
DataCell(Text('43')),
DataCell(Text('Professor')),
],
);
case 2:
return const DataRow(
cells: <DataCell>[
DataCell(Text('William')),
DataCell(Text('27')),
DataCell(Text('Associate Professor')),
],
);
default:
return null;
}
}
@override
bool get isRowCountApproximate => false;
@override
int get selectedRowCount => 0;
}
final DataTableSource dataSource = MyDataSource();
void main() => runApp(const DataTableExampleApp());
class DataTableExampleApp extends StatelessWidget {
const DataTableExampleApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: SingleChildScrollView(
padding: .all(12.0),
child: DataTableExample(),
),
);
}
}
class DataTableExample extends StatelessWidget {
const DataTableExample({super.key});
@override
Widget build(BuildContext context) {
return PaginatedDataTable(
columns: const <DataColumn>[
DataColumn(label: Text('Name')),
DataColumn(label: Text('Age')),
DataColumn(label: Text('Role')),
],
source: dataSource,
);
}
}
This example shows how paginated data tables can supported sorted data.
To see it in action, copy and run this code snippet on DartPad.
import 'package:material_ui/material_ui.dart';
/// Flutter code sample for [PaginatedDataTable].
class MyDataSource extends DataTableSource {
static const List<int> _displayIndexToRawIndex = <int>[0, 3, 4, 5, 6];
late List<List<Comparable<Object>>> sortedData;
void setData(
List<List<Comparable<Object>>> rawData,
int sortColumn,
bool sortAscending,
) {
sortedData = rawData.toList()
..sort((List<Comparable<Object>> a, List<Comparable<Object>> b) {
final Comparable<Object> cellA = a[_displayIndexToRawIndex[sortColumn]];
final Comparable<Object> cellB = b[_displayIndexToRawIndex[sortColumn]];
return cellA.compareTo(cellB) * (sortAscending ? 1 : -1);
});
notifyListeners();
}
@override
int get rowCount => sortedData.length;
static DataCell cellFor(Object data) {
String value;
if (data is DateTime) {
value =
'${data.year}-${data.month.toString().padLeft(2, '0')}-${data.day.toString().padLeft(2, '0')}';
} else {
value = data.toString();
}
return DataCell(Text(value));
}
@override
DataRow? getRow(int index) {
return DataRow.byIndex(
index: sortedData[index][0] as int,
cells: <DataCell>[
cellFor(
'S${sortedData[index][1]}E${sortedData[index][2].toString().padLeft(2, '0')}',
),
cellFor(sortedData[index][3]),
cellFor(sortedData[index][4]),
cellFor(sortedData[index][5]),
cellFor(sortedData[index][6]),
],
);
}
@override
bool get isRowCountApproximate => false;
@override
int get selectedRowCount => 0;
}
void main() => runApp(const DataTableExampleApp());
class DataTableExampleApp extends StatelessWidget {
const DataTableExampleApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: SingleChildScrollView(
padding: .all(12.0),
child: DataTableExample(),
),
);
}
}
class DataTableExample extends StatefulWidget {
const DataTableExample({super.key});
@override
State<DataTableExample> createState() => _DataTableExampleState();
}
class _DataTableExampleState extends State<DataTableExample> {
final MyDataSource dataSource = MyDataSource()..setData(episodes, 0, true);
int _columnIndex = 0;
bool _columnAscending = true;
void _sort(int columnIndex, bool ascending) {
setState(() {
_columnIndex = columnIndex;
_columnAscending = ascending;
dataSource.setData(episodes, _columnIndex, _columnAscending);
});
}
@override
Widget build(BuildContext context) {
return PaginatedDataTable(
sortColumnIndex: _columnIndex,
sortAscending: _columnAscending,
columns: <DataColumn>[
DataColumn(label: const Text('Episode'), onSort: _sort),
DataColumn(label: const Text('Title'), onSort: _sort),
DataColumn(label: const Text('Director'), onSort: _sort),
DataColumn(label: const Text('Writer(s)'), onSort: _sort),
DataColumn(label: const Text('Air Date'), onSort: _sort),
],
source: dataSource,
);
}
}
final List<List<Comparable<Object>>> episodes = <List<Comparable<Object>>>[
<Comparable<Object>>[
1,
1,
1,
'Strange New Worlds',
'Akiva Goldsman',
'Akiva Goldsman, Alex Kurtzman, Jenny Lumet',
DateTime(2022, 5, 5),
],
<Comparable<Object>>[
2,
1,
2,
'Children of the Comet',
'Maja Vrvilo',
'Henry Alonso Myers, Sarah Tarkoff',
DateTime(2022, 5, 12),
],
<Comparable<Object>>[
3,
1,
3,
'Ghosts of Illyria',
'Leslie Hope',
'Akela Cooper, Bill Wolkoff',
DateTime(2022, 5, 19),
],
<Comparable<Object>>[
4,
1,
4,
'Memento Mori',
'Dan Liu',
'Davy Perez, Beau DeMayo',
DateTime(2022, 5, 26),
],
<Comparable<Object>>[
5,
1,
5,
'Spock Amok',
'Rachel Leiterman',
'Henry Alonso Myers, Robin Wasserman',
DateTime(2022, 6, 2),
],
<Comparable<Object>>[
6,
1,
6,
'Lift Us Where Suffering Cannot Reach',
'Andi Armaganian',
'Robin Wasserman, Bill Wolkoff',
DateTime(2022, 6, 9),
],
<Comparable<Object>>[
7,
1,
7,
'The Serene Squall',
'Sydney Freeland',
'Beau DeMayo, Sarah Tarkoff',
DateTime(2022, 6, 16),
],
<Comparable<Object>>[
8,
1,
8,
'The Elysian Kingdom',
'Amanda Row',
'Akela Cooper, Onitra Johnson',
DateTime(2022, 6, 23),
],
<Comparable<Object>>[
9,
1,
9,
'All Those Who Wander',
'Christopher J. Byrne',
'Davy Perez',
DateTime(2022, 6, 30),
],
<Comparable<Object>>[
10,
2,
10,
'A Quality of Mercy',
'Chris Fisher',
'Henry Alonso Myers, Akiva Goldsman',
DateTime(2022, 7, 7),
],
<Comparable<Object>>[
11,
2,
1,
'The Broken Circle',
'Chris Fisher',
'Henry Alonso Myers, Akiva Goldsman',
DateTime(2023, 6, 15),
],
<Comparable<Object>>[
12,
2,
2,
'Ad Astra per Aspera',
'Valerie Weiss',
'Dana Horgan',
DateTime(2023, 6, 22),
],
<Comparable<Object>>[
13,
2,
3,
'Tomorrow and Tomorrow and Tomorrow',
'Amanda Row',
'David Reed',
DateTime(2023, 6, 29),
],
<Comparable<Object>>[
14,
2,
4,
'Among the Lotus Eaters',
'Eduardo Sánchez',
'Kirsten Beyer, Davy Perez',
DateTime(2023, 7, 6),
],
<Comparable<Object>>[
15,
2,
5,
'Charades',
'Jordan Canning',
'Kathryn Lyn, Henry Alonso Myers',
DateTime(2023, 7, 13),
],
<Comparable<Object>>[
16,
2,
6,
'Lost in Translation',
'Dan Liu',
'Onitra Johnson, David Reed',
DateTime(2023, 7, 20),
],
<Comparable<Object>>[
17,
2,
7,
'Those Old Scientists',
'Jonathan Frakes',
'Kathryn Lyn, Bill Wolkoff',
DateTime(2023, 7, 22),
],
<Comparable<Object>>[
18,
2,
8,
'Under the Cloak of War',
'',
'Davy Perez',
DateTime(2023, 7, 27),
],
<Comparable<Object>>[
19,
2,
9,
'Subspace Rhapsody',
'',
'Dana Horgan, Bill Wolkoff',
DateTime(2023, 8, 3),
],
<Comparable<Object>>[
20,
2,
10,
'Hegemony',
'',
'Henry Alonso Myers',
DateTime(2023, 8, 10),
],
];
See also:
- DataTable, which is not paginated.
TableViewfrom the two_dimensional_scrollables package, for displaying large amounts of data without pagination.- material.io/go/design-data-tables
- Inheritance
-
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- PaginatedDataTable
Constructors
-
PaginatedDataTable({Key? key, Widget? header, List<
Widget> ? actions, required List<DataColumn> columns, int? sortColumnIndex, bool sortAscending = true, ValueSetter<bool?> ? onSelectAll, @Deprecated('Migrate to use dataRowMinHeight and dataRowMaxHeight instead. ' 'This feature was deprecated after v3.7.0-5.0.pre.') double? dataRowHeight, double? dataRowMinHeight, double? dataRowMaxHeight, double headingRowHeight = 56.0, double horizontalMargin = 24.0, double columnSpacing = 56.0, bool showCheckboxColumn = true, bool showFirstLastButtons = false, int? initialFirstRowIndex = 0, ValueChanged<int> ? onPageChanged, int rowsPerPage = defaultRowsPerPage, List<int> availableRowsPerPage = const <int>[defaultRowsPerPage, defaultRowsPerPage * 2, defaultRowsPerPage * 5, defaultRowsPerPage * 10], ValueChanged<int?> ? onRowsPerPageChanged, DragStartBehavior dragStartBehavior = DragStartBehavior.start, Color? arrowHeadColor, required DataTableSource source, double? checkboxHorizontalMargin, ScrollController? controller, bool? primary, WidgetStateProperty<Color?> ? headingRowColor, double? dividerThickness, bool showEmptyRows = true}) - Creates a widget describing a paginated DataTable on a Card.
Properties
-
actions
→ List<
Widget> ? -
Icon buttons to show at the top end side of the table. The header must
not be null to show the actions.
final
- arrowHeadColor → Color?
-
Defines the color of the arrow heads in the footer.
final
-
availableRowsPerPage
→ List<
int> -
The options to offer for the rowsPerPage.
final
- checkboxHorizontalMargin → double?
-
Horizontal margin around the checkbox, if it is displayed.
final
-
columns
→ List<
DataColumn> -
The configuration and labels for the columns in the table.
final
- columnSpacing → double
-
The horizontal margin between the contents of each data column.
final
- controller → ScrollController?
-
An object that can be used to control the position to which this scroll
view is scrolled.
final
- dataRowHeight → double?
-
The height of each row (excluding the row that contains column headings).
no setter
- dataRowMaxHeight → double?
-
The maximum height of each row (excluding the row that contains column headings).
final
- dataRowMinHeight → double?
-
The minimum height of each row (excluding the row that contains column headings).
final
- dividerThickness → double?
-
The width of the divider that appears between TableRows.
final
- dragStartBehavior → DragStartBehavior
-
Determines the way that drag start behavior is handled.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- header → Widget?
-
The table card's optional header.
final
-
headingRowColor
→ WidgetStateProperty<
Color?> ? -
The background color for the heading row.
final
- headingRowHeight → double
-
The height of the heading row.
final
- horizontalMargin → double
-
The horizontal margin between the edges of the table and the content
in the first and last cells of each row.
final
- initialFirstRowIndex → int?
-
The index of the first row to display when the widget is first created.
final
- key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
-
onPageChanged
→ ValueChanged<
int> ? -
Invoked when the user switches to another page.
final
-
onRowsPerPageChanged
→ ValueChanged<
int?> ? -
Invoked when the user selects a different number of rows per page.
final
-
onSelectAll
→ ValueSetter<
bool?> ? -
Invoked when the user selects or unselects every row, using the
checkbox in the heading row.
final
- primary → bool?
-
Whether this is the primary scroll view associated with the parent
PrimaryScrollController.
final
- rowsPerPage → int
-
The number of rows to show on each page.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- showCheckboxColumn → bool
-
Whether the widget should display checkboxes for selectable rows.
final
- showEmptyRows → bool
-
Controls the visibility of empty rows on the last page of a
PaginatedDataTable.
final
- showFirstLastButtons → bool
-
Flag to display the pagination buttons to go to the first and last pages.
final
- sortAscending → bool
-
Whether the column mentioned in sortColumnIndex, if any, is sorted
in ascending order.
final
- sortColumnIndex → int?
-
The current primary sort key's column.
final
- source → DataTableSource
-
The data source which provides data to show in each row.
final
Methods
-
createElement(
) → StatefulElement -
Creates a StatefulElement to manage this widget's location in the tree.
inherited
-
createState(
) → PaginatedDataTableState -
Creates the mutable state for this widget at a given location in the tree.
override
-
debugDescribeChildren(
) → List< DiagnosticsNode> -
Returns a list of DiagnosticsNode objects describing this node's
children.
inherited
-
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toDiagnosticsNode(
{String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode -
Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep.
inherited
-
toString(
{DiagnosticLevel minLevel = DiagnosticLevel.info}) → String -
A string representation of this object.
inherited
-
toStringDeep(
{String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String -
Returns a string representation of this node and its descendants.
inherited
-
toStringShallow(
{String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String -
Returns a one-line detailed description of the object.
inherited
-
toStringShort(
) → String -
A short, textual description of this widget.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Constants
- defaultRowsPerPage → const int
- The default value for rowsPerPage.