Flutter 分頁功能表格控制元件詳細解析
前2天有讀者問到是否有帶分頁功能的表格控制元件,今天分頁功能的表格控制元件詳細解析。
PaginatedDataTable
PaginatedDataTable是一個帶分頁功能的DataTable,生成一批資料,專案中此一般通過伺服器獲取,定義model類:
class User { User(this.name,this.age,this.sex); final String name; final int age; final String sex; }
生成資料:
List<User> _data = []; @override void initState() { List.generate(100,(index) { _data.add(User('老孟$index',index % 50,index % 2 == 0 ? '男' : '女')); }); super.initState(); }
PaginatedDataTable的基礎用法如下:
PaginatedDataTable( header: Text('header'),columns: [ DataColumn(label: Text('姓名')),DataColumn(label: Text('性別')),DataColumn(label: Text('年齡')),],source: MyDataTableSource(_data),)
header
表示表格頂部控制元件。
columns
表示每一列的列頭控制元件。
source
表示資料來源,需要繼承DataTableSource,用法如下:
class MyDataTableSource extends DataTableSource { MyDataTableSource(this.data); final List<User> data; @override DataRow getRow(int index) { if (index >= data.length) { return null; } return DataRow.byIndex( index: index,cells: [ DataCell(Text('${data[index].name}')),DataCell(Text('${data[index].sex}')),DataCell(Text('${data[index].age}')),); } @override int get selectedRowCount { return 0; } @override bool get isRowCountApproximate { return false; } @override int get rowCount { return data.length; } }
效果如下:
getRow
是根據index獲取每一行的資料,通常使用DataRow.byIndex返回資料,cells表示每一個表格的資料,cells
的數量需要與PaginatedDataTable中columns
數量保持一致。
selectedRowCount
是選中的行數,注意這裡不是索引,是總共選中的行數。
isRowCountApproximate
:如果isRowCountApproximate
設定為true,行數將會無盡大,所以正常情況下isRowCountApproximate
設定為false。
rowCount
表示行數,如果isRowCountApproximate
設定為true,此屬性無效。
設定actions
,顯示在header
的右端,用法如下:
PaginatedDataTable( header: Text('header'),actions: <Widget>[ IconButton(icon: Icon(Icons.add),onPressed: (){},),IconButton(icon: Icon(Icons.delete),... )
效果如下:
rowsPerPage
表示每頁顯示的行數,預設10行,設定5行如下:
PaginatedDataTable( rowsPerPage: 5,... )
onRowsPerPageChanged
不為null時,在左下角出現每頁顯示多少行數的選項,用法如下:
var _rowsPerPage = 5; PaginatedDataTable( onRowsPerPageChanged: (v) { setState(() { _rowsPerPage = v; }); },availableRowsPerPage: [5,10,15,16],rowsPerPage: _rowsPerPage,... )
效果如下:
點擊出現availableRowsPerPage
設定的陣列,onRowsPerPageChanged
為選擇其中一項後回撥,用於更新rowsPerPage
屬性。
顯示的資料過多時,需要將PaginatedDataTable包裹在SingleChildScrollView中,滾動顯示資料:
SingleChildScrollView( child: PaginatedDataTable() )
onPageChanged
是翻頁時回撥,返回當前頁第一條資料的索引:
PaginatedDataTable( onPageChanged: (page){ print('onPageChanged:$page'); },
列印資料為:
flutter: onPageChanged:10
flutter: onPageChanged:20
flutter: onPageChanged:30
flutter: onPageChanged:40
排序
生序降序設定:
PaginatedDataTable( sortColumnIndex: 1,sortAscending: false,... )
效果如下:
生序降序的設定僅僅顯示相應圖示,資料並不會實際排序,對資料進行排序可以當用戶點選表頭時對資料按照本列資料進行排序,用法如下,
var _sortAscending = true; _buildPaginatedDataTable() { return PaginatedDataTable( header: Text('header'),sortColumnIndex: 2,sortAscending: _sortAscending,columns: [ DataColumn(label: Text('姓名')),DataColumn( label: Text('年齡'),onSort: (index,sortAscending) { setState(() { _sortAscending = sortAscending; if (sortAscending) { _data.sort((a,b) => a.age.compareTo(b.age)); } else { _data.sort((a,b) => b.age.compareTo(a.age)); } }); }),); }
效果如下:
選中
可以在每一行的前面新增複選框,表示當前行是否選中,在User中新增是否選中屬性,用法如下:
class User { User(this.name,this.sex,{this.selected = false}); final String name; final int age; final String sex; bool selected; }
新增勾選框:
@override DataRow getRow(int index) { if (index >= data.length) { return null; } return DataRow.byIndex( index: index,selected: data[index].selected,onSelectChanged: (selected) { data[index].selected = selected; notifyListeners(); },cells: [ DataCell( Text('${data[index].name}'),); }
效果如下:
全選控制:
PaginatedDataTable( header: Text('header'),onSelectAll: (all) { setState(() { _data.forEach((f){ f.selected = all; }); }); },
處理資料顯示不全問題
當表格列比較多的時候,使用SingleChildScrollView包裹,顯示不全時滾動顯示,用法如下:
SingleChildScrollView( scrollDirection: Axis.horizontal,child: PaginatedDataTable() )
效果如下:
交流
老孟Flutter部落格地址(近200個控制元件用法):http://laomengit.com