When trying to show the list, for the fixed type database table display need to support left and right sliding, understand the PaginatedDataTable table, learn about the design idea;
PaginatedDataTable
Source code analysis
PaginatedDataTable({Key Key, @required this.header, // table title this.actions, // button on the right of title @required this.columns, // This. SortAscending = true, // this. OnSelectAll, this. / / selection callback enclosing dataRowHeight = kMinInteractiveDimension, / / table row high enclosing headingRowHeight = 56.0, This. columnSpacing = 56.0, // Cell spacing this.showCheckboxColumn = true, Recessive this. / / marquee initialFirstRowIndex = 0, / / initializes the starting index enclosing onPageChanged, / / page switching callback enclosing rowsPerPage = defaultRowsPerPage, / / data for this article. Each page availableRowsPerPage = const < int > [defaultRowsPerPage, DefaultRowsPerPage * 2, defaultRowsPerPage * 5, 10] defaultRowsPerPage *, / / the number of rows per page change list this. OnRowsPerPageChanged, This. dragStartBehavior = dragStartBehavior. start, @required this.source, // Data source})Copy the code
Simple analysis source code can be obtained, PaginatedDataTable is extended from DataTable, and Card package; The difference is that pagination datatable supports pagination;
The paged form is divided into five parts: DataTable overall DataTable, DataColumn horizontal data header, DataRow vertical DataTable, DataCell DataTable cell, and DataTableSource.
The PaginatedDataTable table also uses columns to encapsulate header headers with the DataTable table and footer pagination button.
Case try
1. header & columns & source
Header & Columns & Source as the basic PaginatedDataTable three necessary properties; Header is used as the title of the table and cannot be empty. It is recommended to use Text as well as ButtonBar button container, and other daily widgets are also available.
Columns, as the data table header, is a DataColumn list. The length of the list should be the same as that of the source resource list array. Table header information can be displayed through label, and list sorting can also be monitored through onSort callback.
Source is the data source from the DataTableSource class; Main four abstract method, respectively is getRow () according to the content index for line, rowCount data source line number, to confirm whether isRowCountApproximate line number and selectedRowCount selected the number of rows (not selected array but selected number);
class _PaginatedPageState extends State<PaginatedDataTablePage> { DataTableSource _sourceData = SourceData(); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('PaginatedDataTable Page')), body: Column(children: [ SizedBox(height: 10), PaginatedDataTable( source: _sourceData, header: Text('Flight Products'), columns: [ DataColumn(label: Text('Avatar')), DataColumn(label: Text('ID')), DataColumn(label: Text('Name')), DataColumn(label: Row(children: [ Text('Price'), SizedBox(width: 5.0), Icon(icon.airplanemode_active)])), DataColumn(label: Text('No ')), DataColumn(label: Text('Address'))]))); } } class SourceData extends DataTableSource { final List<Map<String, dynamic>> _sourceData = List.generate( 200, (index) => { "avatar": (index % 3 == 1) ? 'images/icon_hzw01.jpg' : (index % 3 == 2) ? 'images/icon_hzw03.jpg' : 'images/icon_music.png', "id": (index + 1), "name": "Item Name ${(index + 1)}", "price": Random().nextInt(10000), "no.": Random().nextInt(10000), "address": (index % 3 == 1) ? 'Beijing' : (index % 3 == 2) ? 'New York' : 'Los Angeles' }); bool get isRowCountApproximate => false; int get rowCount => _sourceData.length; int get selectedRowCount => 0; DataRow getRow(int index) => DataRow(cells: [ DataCell(CircleAvatar(backgroundImage: AssetImage(_sourceData[index]["avatar"]))), DataCell(Text(_sourceData[index]['id'].toString())), DataCell(Text(_sourceData[index]['name'])), DataCell(Text('\$ ${_sourceData[index]['price']}')), DataCell(Text(_sourceData[index]['no.'].toString())), DataCell(Text(_sourceData[index]['address'].toString())) ]); }Copy the code
2. actions & headingRowHeight
The title content of the data table is mainly displayed through the header, while the source title is a Row structure. You can add widgets such as ICONS on the right through actions, similar to the ToolBar. You can also adjust the overall height of the header row through headingRowHeight, which defaults to 56.0;
Header: Text('Flight Products'), Actions: [Icon(Icons. Refresh), Icon(Icons. Clear)], headingRowHeight: 80.0,Copy the code
3. dataRowHeight & horizontalMargin & columnSpacing
DataRowHeight is the data element row height, default is 48.0; HorizontalMargin is the margin between the first and last columns of the table. Default is 24.0. ColumnSpacing is the spacing between cells. The default value is 56.0.
DataRowHeight: 60.0, horizontalMargin: 40.0, columnSpacing: 80.0,Copy the code
4. rowsPerPage & initialFirstRowIndex & onPageChanged
RowsPerPage indicates the number of items to display per page. Default is 10. OnPageChanged: callback for left/right page switch. The result of callback is the data index value. InitialFirstRowIndex indicates the location of the initial display index. Note that if the number of front data items does not meet the requirements of the integer page, the previous page of the integer page is taken.
rowsPerPage: 9,
initialFirstRowIndex: 20,
onPageChanged: (i) => print('onPageChanged -> $i'),
Copy the code
5. availableRowsPerPage & onRowsPerPageChanged
OnRowsPerPageChanged if not empty sets the number of rows per page shown in the lower left corner; At this time, availableRowsPerPage list cannot be empty, and the side dish test, the first element of the list must be consistent with the number of initialized rows;
var _rowsPerPage = 8;
rowsPerPage: _rowsPerPage,
availableRowsPerPage: [8, 16, 20],
onRowsPerPageChanged: (value) => setState(() => _rowsPerPage = value),
Copy the code
6. sortAscending & sortColumnIndex
SortAscending is used to set the ascending or descending order of the table data. This function is used together with the onSort() callback in the DataColumn. SortColumnIndex corresponds to an ascending or descending index of the header array.
PaginatedDataTable( source: _sourceData, header: Text('Flight Products'), actions: [Icon(Icons. Refresh), Icon(Icons. Clear)], headingRowHeight: 50.0, dataRowHeight: 60.0, rowsPerPage: _rowsPerPage, onPageChanged: (i) => print('onPageChanged -> $i'), availableRowsPerPage: [8, 16, 20], onRowsPerPageChanged: (value) => setState(() => _rowsPerPage = value), sortAscending: _sortAscending, sortColumnIndex: 1, columns: [ DataColumn(label: Text('Avatar')), DataColumn( label: Text('ID'), onSort: (index, sortAscending) { setState(() { _sortAscending = sortAscending; _sourceData.sortData((map) => map['id'], sortAscending); }); }), DataColumn(label: Text('Name')), DataColumn(label: Row(children: [Text('Price'), SizedBox(width: 5.0), ![Table06.gif](https://upload-images.jianshu.io/upload_images/6187924-9fcfbafc05579b6b.gif?imageMogr2/auto-orient/strip) Icon(Icons.airplanemode_active) ])), DataColumn(label: Text('No.')), DataColumn(label: Text('Address')) ]) void sortData<T>(Comparable<T> getField(Map<String, dynamic> map), bool b) { _sourceData.sort((Map<String, dynamic> map1, Map<String, dynamic> map2) { if (! B) {final Map<String, dynamic> temp = map1; map1 = map2; map2 = temp; } final Comparable<T> s1Value = getField(map1); final Comparable<T> s2Value = getField(map2); return Comparable.compare(s1Value, s2Value); }); notifyListeners(); }Copy the code
7. showCheckboxColumn & onSelectAll
ShowCheckboxColumn is used implicitly and explicitly for multiple checkboxes, provided that the DataRow in the DataTableSource data source has the Selected property set; OnSelectAll is a callback for all, and the status needs to be updated by itself;
showCheckboxColumn: true, onSelectAll: (state) => setState(() => _sourceData.selectAll(state)), DataRow getRow(int index) => DataRow.byIndex( index: index, selected: _sourceData[index]["selected"], onSelectChanged: (selected) { _sourceData[index]["selected"] = selected; notifyListeners(); }, cells: [ DataCell(CircleAvatar(backgroundImage: AssetImage(_sourceData[index]["avatar"]))), DataCell(Text(_sourceData[index]['id'].toString())), DataCell(Text(_sourceData[index]['name'])), DataCell(Text('\$ ${_sourceData[index]['price']}')), DataCell(Text(_sourceData[index]['no.'].toString())), DataCell(Text(_sourceData[index]['address'].toString())) ]); void selectAll(bool checked) { _sourceData.forEach((data) => data["selected"] = checked); _selectCount = checked ? _sourceData.length : 0; notifyListeners(); // Notify the listener to flush}Copy the code
PaginatedDataTable case source code
PaginatedDataTable mainly calculates cell position by applyPaintTransform through RenderObject; Side dish to its attempt is not deep enough, if there is a mistake, please guide!
Source: Young Monk Atze