DataTable控件显示表格数据,DataTable需要设置行和列。

DataTable

  1. DataTable({
  2. Key key,
  3. @required this.columns, //是DataTable的列
  4. @required this.rows, //是DataTable的每一行数据
  5. this.sortColumnIndex, //表示表格显示排序图标的索引
  6. this.sortAscending = true, //表示升序或者降序(默认是升序)
  7. this.onSelectAll,
  8. this.dataRowColor, //行背景色
  9. this.dataRowHeight, //行高度
  10. this.dataTextStyle, // 行文字样式
  11. this.headingRowColor, //表头背景色 headingRowColor: MaterialStateProperty.all(Colors.red),
  12. this.headingRowHeight, //表头行高度
  13. this.headingTextStyle, //表头文字样式
  14. this.horizontalMargin, //表格左右边距
  15. this.columnSpacing, //列间隔
  16. this.showCheckboxColumn = true,
  17. this.showBottomBorder = false, //是否展示底部边框
  18. this.dividerThickness, //分割线粗细
  19. })


简单示例

image.png

  1. DataTable(
  2. // 表头
  3. columns: [
  4. DataColumn(label: Text('姓名')),
  5. DataColumn(label: Text('年龄')),
  6. ],
  7. rows: [
  8. // 单行数据
  9. DataRow(cells: [
  10. DataCell(Text('张三')),
  11. DataCell(Text('20')),
  12. ]),
  13. DataRow(cells: [
  14. DataCell(Text('李四')),
  15. DataCell(Text('24')),
  16. ]),
  17. ],
  18. ),

DataColumn

  1. const DataColumn({
  2. @required this.label, //标签,文本或者size=18的图标
  3. this.tooltip, //长按提示。 tooltip: '长按提示',
  4. this.numeric = false, //是否包含数字,该包含数字数据的列的单元格内容是否右对齐
  5. this.onSort, //排序时调用
  6. }) : assert(label != null);

显示排序图标

image.png

  1. DataTable(
  2. sortColumnIndex: 1, //表示表格显示排序图标的索引
  3. sortAscending: true, //表示是否是升序
  4. columns: [
  5. DataColumn(label: Text('姓名')),
  6. DataColumn(
  7. label: Text('年龄'),
  8. onSort: (int columnIndex, bool ascending) {
  9. print('$columnIndex -- $ascending');
  10. // columnIndex 表示索引
  11. // ascending 表示变化之后的排序状态
  12. },
  13. ),
  14. ],
  15. ...
  16. )

多列排序示例

s.gif

  1. import "package:flutter/material.dart";
  2. import 'package:app1/coms/base/empty_null/empty_null.dart';
  3. class TestPage extends StatefulWidget {
  4. @override
  5. _TestPageState createState() => _TestPageState();
  6. }
  7. class _TestPageState extends State<TestPage> {
  8. List<User> data = [
  9. User('张三', 18),
  10. User('李四', 244),
  11. User('王五', 2),
  12. User('马六', 3438),
  13. ];
  14. int _sortColumnIndex = 0; //排序索引
  15. bool _sortAscending = true; //是否升序
  16. @override
  17. Widget build(BuildContext context) {
  18. return Scaffold(
  19. appBar: EmptyNull.appBar(),
  20. body: Container(
  21. child: DataTable(
  22. sortColumnIndex: _sortColumnIndex,
  23. sortAscending: _sortAscending,
  24. columns: [
  25. DataColumn(
  26. label: Text('姓名'),
  27. onSort: (int columnIndex, bool ascending) {
  28. setState(() {
  29. _sortColumnIndex = columnIndex;
  30. _sortAscending = ascending;
  31. if (ascending) {
  32. data.sort((a, b) => a.name.compareTo(b.name));
  33. } else {
  34. data.sort((a, b) => b.name.compareTo(a.name));
  35. }
  36. });
  37. },
  38. ),
  39. DataColumn(
  40. label: Text('年龄'),
  41. onSort: (int columnIndex, bool ascending) {
  42. setState(() {
  43. _sortColumnIndex = columnIndex;
  44. _sortAscending = ascending;
  45. if (ascending) {
  46. data.sort((a, b) => a.age.compareTo(b.age));
  47. } else {
  48. data.sort((a, b) => b.age.compareTo(a.age));
  49. }
  50. });
  51. },
  52. ),
  53. ],
  54. rows: data
  55. .map((item) => DataRow(
  56. cells: [
  57. DataCell(Text('${item.name}')),
  58. DataCell(Text('${item.age}')),
  59. ],
  60. ))
  61. .toList(),
  62. ),
  63. ),
  64. );
  65. }
  66. }
  67. class User {
  68. User(this.name, this.age, {this.selected = false});
  69. String name;
  70. int age;
  71. bool selected;
  72. }

包含数字的列是否右对齐 numeric

默认情况下数据是左对齐的,让某一列右对齐只需设置DataColumn中numeric参数true。
image.png

  1. columns: [
  2. DataColumn(label: Text('姓名')),
  3. DataColumn(label: Text('年龄'), numeric: true),
  4. ],

DataRow

  1. const DataRow({
  2. this.key,
  3. this.selected = false, //行是否被选中
  4. this.onSelectChanged, //点击行选中改变回调
  5. this.color,
  6. @required this.cells, //子项
  7. }) : assert(cells != null);

选中示例

设置DataRow中 selected 参数为true,可以显示其中一行被选中。
onSelectChanged 参数是点击每一行数据时的回调。
fdtdttyddasdyrt.gif

我们并没有对全选、取消全选进行控制,但是演示发现:全选、取消全选时,真实数据也发生了变化,那么是怎么实现的? 答:全选、取消全选时,每一行的onSelectChanged都被回调了一次。

  1. import "package:flutter/material.dart";
  2. import 'package:app1/coms/base/empty_null/empty_null.dart';
  3. class TestPage extends StatefulWidget {
  4. @override
  5. _TestPageState createState() => _TestPageState();
  6. }
  7. class _TestPageState extends State<TestPage> {
  8. List<User> data = [
  9. User('张三', 18),
  10. User('李四', 244),
  11. User('王五', 2),
  12. User('马六', 3438),
  13. ];
  14. @override
  15. Widget build(BuildContext context) {
  16. return Scaffold(
  17. appBar: EmptyNull.appBar(),
  18. body: Container(
  19. child: DataTable(
  20. columns: [
  21. DataColumn(label: Text('姓名')),
  22. DataColumn(label: Text('年龄')),
  23. ],
  24. rows: data
  25. .map((item) => DataRow(
  26. selected: item.selected,
  27. onSelectChanged: (selected) {
  28. print('${item.name} -- $selected');
  29. setState(() {
  30. item.selected = selected;
  31. });
  32. },
  33. cells: [
  34. DataCell(Text('${item.name}')),
  35. DataCell(Text('${item.age}')),
  36. ],
  37. ))
  38. .toList(),
  39. ),
  40. ),
  41. );
  42. }
  43. }
  44. class User {
  45. User(this.name, this.age, {this.selected = false});
  46. String name;
  47. int age;
  48. bool selected;
  49. }

DataCell

DataCell是DataRow中每一个子控件,DataCell子控件不一定是文本,也可以是图标等任意组件。

  1. const DataCell(
  2. this.child, { //子部件,一般为Text或DropdownButton
  3. this.placeholder = false, //是否为占位符,若child为Text,显示占位符文本样式
  4. this.showEditIcon = false, //显示编辑图标,并非意义上的把child变为可编辑,需要结合onTap
  5. this.onTap, //点击
  6. }) : assert(child != null);

给DataCell设置编辑图标:
image.png

  1. DataCell(Text('name'),showEditIcon: true)

当然仅仅是一个图标,placeholder参数也是一样的,设置为true,仅仅是文字的样式变化了,onTap为点击回调,用法如下:
image.png

  1. DataCell(
  2. Text('name'),
  3. placeholder: true,
  4. showEditIcon: true,
  5. onTap: (){
  6. print('DataCell onTap');
  7. },
  8. )

处理数据显示不全问题

当表格列比较多的时候,可以使用SingleChildScrollView包裹DataTable,显示不全时滚动显示。