注意:無特殊說明,Flutter版本及Dart版本如下:
- Flutter版本: 1.12.13+hotfix.5
- Dart版本: 2.7.0
DataTable
DataTable控制元件顯示錶格資料,DataTable需要設定行和列,用法如下:
DataTable(
columns: [
DataColumn(label: Text('姓名')),
DataColumn(label: Text('年齡')),
],
rows: [
DataRow(cells: [
DataCell(Text('老孟')),
DataCell(Text('18')),
]),
],
)
複製程式碼
columns
引數是DataTable的列,rows
引數是DataTable的每一行資料,效果如下:
![image-20200303200953329](/Users/mengqingdong/Library/Application Support/typora-user-images/image-20200303200953329.png)
在新增一行資料,只需要新增一個DataRow即可,用法如下:
DataTable(
...
rows: [
DataRow(cells: [
DataCell(Text('老孟')),
DataCell(Text('18')),
]),
DataRow(cells: [
DataCell(Text('大黃')),
DataCell(Text('20')),
]),
],
)
複製程式碼
在表頭顯示排序圖示:
DataTable(
sortColumnIndex: 1,
sortAscending: true,
...
)
複製程式碼
sortColumnIndex
參數列示表格顯示排序圖示的索引,sortAscending
參數列示升序或者降序,效果如下:
這裡要注意DataTable本身不能對資料進行排序,這些引數僅僅是外觀上的控制。
DataColumn
預設情況下資料是左對齊的,讓某一列右對齊只需設定DataColumn中numeric
引數true,設定如下:
DataTable(
columns: [
DataColumn(label: Text('姓名')),
DataColumn(label: Text('年齡'),numeric: true),
],
...
)
複製程式碼
效果:
設定DataColumn中tooltip
參數列示當長安此表頭時顯示提示,用法如下:
DataColumn(label: Text('姓名'),tooltip: '長按提示')
複製程式碼
長按提示:
onSort
回撥是使用者點選表頭(DataColumn)時的回撥,onSort
中第一個引數columnIndex
表示索引,ascending
參數列示升序或者降序,用法如下:
DataColumn(label: Text('年齡'), onSort: (int columnIndex, bool ascending){
//排序演算法
}),
複製程式碼
DataRow
可以顯示其中一行被選中,設定DataRow中selected
引數為true,用法如下:
DataRow(
selected: true,
...
)
複製程式碼
效果如下:
onSelectChanged
引數是點選每一行資料時的回撥,用法如下:
DataRow(
onSelectChanged: (selected){
}
...
)
複製程式碼
設定了onSelectChanged
引數,在資料的每一行和表頭的前面顯示勾選框,效果如下:
當然現在點選還不能顯示選中的效果,增加選中效果,修改User model類,增加selected
屬性,表示當前行是否選中:
class User {
User(this.name, this.age, {this.selected = false});
String name;
int age;
bool selected;
}
複製程式碼
修改資料:
List<User> data = [
User('老孟', 18),
User('老孟1', 19,selected: true),
User('老孟2', 20),
User('老孟3', 21),
User('老孟4', 22),
];
複製程式碼
構建DataTable:
List<DataRow> dateRows = [];
for (int i = 0; i < data.length; i++) {
dateRows.add(DataRow(
selected: data[i].selected,
onSelectChanged: (selected){
setState(() {
data[i].selected = selected;
});
},
cells: [
DataCell(Text('${data[i].name}')),
DataCell(Text('${data[i].age}')),
],
));
}
return DataTable(columns: [
DataColumn(label: Text('姓名')),
DataColumn(
label: Text('年齡'),
),
], rows: dateRows);
複製程式碼
效果如下:
我們並沒有對錶頭的全選/取消全選勾選框進行控制,一個很大的疑問:點選全選/取消全選勾選框,如果都勾選了,真實資料是否也發生變化了,對應本示例就是User中的selected
引數是否全部為true,可以肯定的告訴你User中的selected
引數已經全部變為true了,那是如何實現的呢?非常簡單,每一行的onSelectChanged
都被回撥了一次。
DataCell
DataCell是DataRow中每一個子控制元件,DataCell子控制元件不一定是文字,也可以是圖示等任意元件,我們可以給DataCell設定編輯圖示:
DataCell(Text('name'),showEditIcon: true)
複製程式碼
效果如下:
當然僅僅是一個圖示,placeholder
引數也是一樣的,設定為true,僅僅是文字的樣式變化了,onTap
為點選回撥,用法如下:
DataCell(Text('name'),showEditIcon: true,onTap: (){
print('DataCell onTap');
},placeholder: true)
複製程式碼
效果如下:
排序
DateTable本身是沒有排序功能的,當使用者點選表頭時對資料按照本列資料進行排序,用法如下,
資料model類:
class User {
User(this.name, this.age);
final String name;
final int age;
}
複製程式碼
初始化資料及預設排序:
List<User> data = [
User('老孟', 18),
User('老孟1', 19),
User('老孟2', 20),
User('老孟3', 21),
User('老孟4', 22),
];
var _sortAscending = true;
複製程式碼
構建DataTable:
DataTable(
sortColumnIndex: 1,
sortAscending: _sortAscending,
columns: [
DataColumn(label: Text('姓名')),
DataColumn(label: Text('年齡'), onSort: (int columnIndex, bool ascending){
setState(() {
_sortAscending = ascending;
if(ascending){
data.sort((a, b) => a.age.compareTo(b.age));
}else {
data.sort((a, b) => b.age.compareTo(a.age));
}
});
}),
],
rows: data.map((user) {
return DataRow(cells: [
DataCell(Text('${user.name}')),
DataCell(Text('${user.age}')),
]);
}).toList())
複製程式碼
效果如下:
如果想給姓名
列也加上排序呢,修改如下:
var _sortAscending = true;
var _sortColumnIndex =0;
DataTable(
sortColumnIndex: _sortColumnIndex,
sortAscending: _sortAscending,
columns: [
DataColumn(label: Text('姓名'),onSort: (int columnIndex, bool ascending){
setState(() {
_sortColumnIndex = columnIndex;
_sortAscending = ascending;
if(ascending){
data.sort((a, b) => a.name.compareTo(b.name));
}else {
data.sort((a, b) => b.name.compareTo(a.name));
}
});
}),
DataColumn(label: Text('年齡'), onSort: (int columnIndex, bool ascending){
setState(() {
_sortColumnIndex = columnIndex;
_sortAscending = ascending;
if(ascending){
data.sort((a, b) => a.age.compareTo(b.age));
}else {
data.sort((a, b) => b.age.compareTo(a.age));
}
});
}),
],
...
)
複製程式碼
效果如下:
處理資料顯示不全問題
當表格列比較多的時候,可以使用SingleChildScrollView包裹DataTable,顯示不全時滾動顯示,用法如下:
List<DataRow> dateRows = [];
for (int i = 0; i < data.length; i++) {
dateRows.add(DataRow(
cells: [
DataCell(Text('${data[i].name}')),
DataCell(Text('${data[i].age}')),
DataCell(Text('男')),
DataCell(Text('2020')),
DataCell(Text('10')),
],
));
}
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(columns: [
DataColumn(label: Text('姓名')),
DataColumn(
label: Text('年齡'),
),
DataColumn(
label: Text('性別'),
),
DataColumn(
label: Text('出生年份'),
),
DataColumn(
label: Text('出生月份'),
),
], rows: dateRows),
);
複製程式碼
效果如下: