DataTable 是 flutter 提供的一个表格控件
1. DataTable
属性介绍
DataTable 属性 | 介绍 |
---|---|
columns | @required 列数组 <DataColumn> |
sortColumnIndex | 有排列箭头的列,仅仅是展示箭头 |
sortAscending | 是否升序,默认为 true, 排列顺序,仅仅是箭头向上还是向下 |
onSelectAll | 左上角全选按钮点击回调 |
dataRowHeight | Rows 中每条 Row 高度,默认为 kMinInteractiveDimension = 48.0 |
headingRowHeight | 顶部 Row 高度,默认为 56.0 |
horizontalMargin | 左侧边距,默认为 24.0 |
columnSpacing | 每一列间距,默认为 56.0 |
showCheckboxColumn | 是否展示左侧 checkbox 这一列,默认为 true |
dividerThickness | 分割线宽度,默认为 1.0 |
rows | @required 行数组 <DataRow> |
DataColumn 属性 | 介绍 |
---|---|
label | 文本 |
tooltip | 长按提示 |
numeric | 是否居右,默认为 false |
onSort | 点击排序箭头回调函数 |
DataRow 属性 | 介绍 |
---|---|
selected | checkbox 是否选中,默认为 false |
onSelectChanged | 左侧 checkbox 点击事件 |
color | DataRow 颜色回调函数 |
cells | <DataCell> 数组 |
DataCell 属性 | 介绍 |
---|---|
child | 子控件 |
placeholder | 是否为 placeholder,会改变 Text 样式 |
showEditIcon | 是否展示编辑按钮 |
onTap | 点击事件 |
2. 基本使用
class MSDataTableDemo extends StatefulWidget {
const MSDataTableDemo({Key? key}) : super(key: key);
@override
State<MSDataTableDemo> createState() => _MSDataTableDemoState();
}
class _MSDataTableDemoState extends State<MSDataTableDemo> {
List<MSDataRowModel> _datas = [];
@override
void initState() {
_datas.add(MSDataRowModel("劫", "刺客", "20", "2800"));
_datas.add(MSDataRowModel("烬", "射手", "30", "3200"));
_datas.add(MSDataRowModel("提莫", "法师", "23", "2500"));
_datas.add(MSDataRowModel("洛克", "战士", "30", "3550"));
_datas.add(MSDataRowModel("拉克丝", "法师", "18", "2000"));
_datas.add(MSDataRowModel("武器大师", "战士", "19", "1800"));
_datas.add(MSDataRowModel("慎", "坦克", "25", "2600"));
_datas.add(MSDataRowModel("盖伦", "战士", "25", "2800"));
_datas.add(MSDataRowModel("皇子", "战士", "25", "2600"));
_datas.add(MSDataRowModel("盲僧", "刺客", "25", "2800"));
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("DataTableDemo")),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: _dataTable(),
),
),
);
}
_dataTable() {
return DataTable(
columns: _dataColumnList(),
rows: _dataRowList(),
dataRowHeight: 60, // Rows 中每条 Row 高度
headingRowHeight: 100, // 顶部 Row 高度
horizontalMargin: 20, // 左侧边距
columnSpacing: 80, // 每一列间距
showCheckboxColumn:
true, // 是否展示左侧 checkbox,默认为 true,需要和 DataRow 的onSelectChanged 一起使用
dividerThickness: 2, // 分割线宽度
// 左上角全选按钮点击回调 如果实现此函数,需要手动实现全选功能
// onSelectAll: (boolValue) {
// print("DataTable onSelectAll");
// },
);
}
List<DataColumn> _dataColumnList() {
List<DataColumn> columns = [];
columns.add(DataColumn(label: Text("名字")));
columns.add(DataColumn(label: Text("类型")));
columns.add(DataColumn(label: Text("等级")));
columns.add(DataColumn(
label: Text("战力"),
tooltip: "英雄战斗力", // 长按提示
numeric: false, // 是否居右,默认为 false
));
return columns;
}
List<DataRow> _dataRowList() {
List<DataRow> rows = [];
_datas.forEach((element) {
rows.add(DataRow(
cells: [
DataCell(Text(element.name)),
DataCell(Text(element.type)),
DataCell(Text(element.level)),
DataCell(
Text(element.fightingCapacity),
// 点击事件
onTap: () {
print("DataCell.onTap");
},
placeholder:
true, // 是否是 placeholder,默认为 false,设置为 true 时 Text 会变成灰色 placeholder
showEditIcon: true, //是否展示编辑图标
),
],
onSelectChanged: (select) {
element.onSelected = select!;
setState(() {});
},
selected: element.onSelected, // 左侧 checkbox 是否选中
color: MaterialStateProperty.resolveWith((states) {
if (states.contains(MaterialState.selected)) {
return Colors.amber;
} else {
return Colors.grey[100];
}
}),
));
});
return rows;
}
}
class MSDataRowModel {
String name;
String fightingCapacity;
String type;
String level;
bool onSelected = false;
MSDataRowModel(this.name, this.type, this.level, this.fightingCapacity);
}

3. 排序
在 DataTable 提供的属性中,仅仅是一个箭头展示效果和点击事件而已,如果需要点击切换排序,还需要自定义代码来排序,然后刷新页面才可以。
return DataTable(
...
sortColumnIndex: 3, // 有排列箭头的列,仅仅是展示箭头 需和对应的DataColumn中的onSort 一起使用
sortAscending: _sortAscending, // 排列顺序,仅仅是箭头向上还是向下
...
);
List<DataColumn> _dataColumnList() {
List<DataColumn> columns = [];
...
columns.add(DataColumn(
...
onSort: (columnIndex, ascending) {
print("index = $columnIndex, booValue = $ascending");
_sortAscending = ascending;
_sortDatas();
setState(() {});
},
));
return columns;
}
_sortDatas() {
if (_sortAscending) {
_datas.sort((a, b) {
return int.parse(a.fightingCapacity)
.compareTo(int.parse(b.fightingCapacity));
});
} else {
_datas.sort((a, b) {
return int.parse(b.fightingCapacity)
.compareTo(int.parse(a.fightingCapacity));
});
}
}
完整代码
class MSDataTableDemo extends StatefulWidget {
const MSDataTableDemo({Key? key}) : super(key: key);
@override
State<MSDataTableDemo> createState() => _MSDataTableDemoState();
}
class _MSDataTableDemoState extends State<MSDataTableDemo> {
List<MSDataRowModel> _datas = [];
bool _sortAscending = true;
@override
void initState() {
_datas.add(MSDataRowModel("劫", "刺客", "20", "2800"));
_datas.add(MSDataRowModel("烬", "射手", "30", "3200"));
_datas.add(MSDataRowModel("提莫", "法师", "23", "2500"));
_datas.add(MSDataRowModel("洛克", "战士", "30", "3550"));
_datas.add(MSDataRowModel("拉克丝", "法师", "18", "2000"));
_datas.add(MSDataRowModel("武器大师", "战士", "19", "1800"));
_datas.add(MSDataRowModel("慎", "坦克", "25", "2600"));
_datas.add(MSDataRowModel("盖伦", "战士", "25", "2800"));
_datas.add(MSDataRowModel("皇子", "战士", "25", "2600"));
_datas.add(MSDataRowModel("盲僧", "刺客", "25", "2800"));
_sortDatas();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("DataTableDemo")),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: _dataTable(),
),
),
);
}
_dataTable() {
return DataTable(
columns: _dataColumnList(),
rows: _dataRowList(),
dataRowHeight: 60, // Rows 中每条 Row 高度
headingRowHeight: 100, // 顶部 Row 高度
horizontalMargin: 20, // 左侧边距
columnSpacing: 80, // 每一列间距
showCheckboxColumn:
true, // 是否展示左侧 checkbox,默认为 true,需要和 DataRow 的onSelectChanged 一起使用
dividerThickness: 2, // 分割线宽度
sortColumnIndex: 3, // 有排列箭头的列,仅仅是展示箭头 需和对应的DataColumn中的onSort 一起使用
sortAscending: _sortAscending, // 排列顺序,仅仅是箭头向上还是向下
// 左上角全选按钮点击回调 如果实现此函数,需要手动实现全选功能
// onSelectAll: (boolValue) {
// print("DataTable onSelectAll");
// },
);
}
List<DataColumn> _dataColumnList() {
List<DataColumn> columns = [];
columns.add(DataColumn(label: Text("名字")));
columns.add(DataColumn(label: Text("类型")));
columns.add(DataColumn(label: Text("等级")));
columns.add(DataColumn(
label: Text("战力"),
tooltip: "英雄战斗力", // 长按提示
numeric: false, // 是否居右,默认为 false
onSort: (columnIndex, ascending) {
print("index = $columnIndex, booValue = $ascending");
_sortAscending = ascending;
_sortDatas();
setState(() {});
},
));
return columns;
}
List<DataRow> _dataRowList() {
List<DataRow> rows = [];
_datas.forEach((element) {
rows.add(DataRow(
cells: [
DataCell(Text(element.name)),
DataCell(Text(element.type)),
DataCell(Text(element.level)),
DataCell(
Text(element.fightingCapacity),
// 点击事件
onTap: () {
print("DataCell.onTap");
},
placeholder:
true, // 是否是 placeholder,默认为 false,设置为 true 时 Text 会变成灰色 placeholder
showEditIcon: true, //是否展示编辑图标
),
],
onSelectChanged: (select) {
element.onSelected = select!;
setState(() {});
},
selected: element.onSelected, // 左侧 checkbox 是否选中
color: MaterialStateProperty.resolveWith((states) {
if (states.contains(MaterialState.selected)) {
return Colors.amber;
} else {
return Colors.grey[100];
}
}),
));
});
return rows;
}
_sortDatas() {
if (_sortAscending) {
_datas.sort((a, b) {
return int.parse(a.fightingCapacity)
.compareTo(int.parse(b.fightingCapacity));
});
} else {
_datas.sort((a, b) {
return int.parse(b.fightingCapacity)
.compareTo(int.parse(a.fightingCapacity));
});
}
}
}
class MSDataRowModel {
String name;
String fightingCapacity;
String type;
String level;
bool onSelected = false;
MSDataRowModel(this.name, this.type, this.level, this.fightingCapacity);
}

注意 我们的 fightingCapacity 用的是 String 类型,如果不转换直接比较,排序会出现问题。
网友评论