Flutter DataTable
的bug
在使用原生控件DataTable
时,会发现表内单元格的内容无法居中,单元格右侧会多出一段。这实际是DataTable
的一个bug, DataTable
的部分源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class DataTable extends Stateless {
//...
Widget build(BuildContext context) {
//...
tableRows[0].children[displayColumnIndex] = _buildHeadingCell(
context: context,
padding: padding,
label: column.label,
tooltip: column.tooltip,
numeric: column.numeric,
//1.这里的onSort一定是不等于null的
onSort: () => column.onSort != null ? column.onSort(dataColumnIndex, sortColumnIndex != dataColumnIndex || !sortAscending) : null,
sorted: dataColumnIndex == sortColumnIndex,
ascending: sortAscending,
);
}
//...
Widget _buildHeadingCell({
BuildContext context,
EdgeInsetsGeometry padding,
Widget label,
String tooltip,
bool numeric,
VoidCallback onSort,
bool sorted,
bool ascending,
}) {
//2.导致这个if判断是一定会执行的
if (onSort != null) {
//arrow的宽度是16
final Widget arrow = _SortArrow(
visible: sorted,
down: sorted ? ascending : null,
duration: _sortArrowAnimationDuration,
);
//arrowPadding的宽度是2
const Widget arrowPadding = SizedBox(width: _sortArrowPadding);
//这样,会导致单元格的后面,多出18的长度
label = Row(
textDirection: numeric ? TextDirection.rtl : null,
children: <Widget>[ label, arrowPadding, arrow ],
);
}
//...
}
}
所以,需要将上面注释1的代码,改成下面这样就可以了:
1
onSort: column.onSort != null ? () => column.onSort(dataColumnIndex, sortColumnIndex != dataColumnIndex || !sortAscending) : null,
升级DataTable
原生DataTable
其实不是很好用,单元格无法对齐,无法设置背景颜色,没有网格线等等。
通过封装的EnhanceDataTable
支持设置背景颜色、单元格自动居中、支持网格线、首行首列固定的优点。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import 'package:flutter/material.dart'
hide DataTable, DataColumn, DataRow, DataCell;
import 'data_table.dart';
class EnhanceDataTable<T> extends StatefulWidget {
//是否固定第一行
final bool fixedFirstRow;
//是否固定第一列
final bool fixedFirstCol;
//包括header以及cell内容的list
final List<List<T>> rowsCells;
//支持自定义单元格格式
final Widget Function(T data) cellBuilder;
//单元格高度
final double cellHeight;
//单元格两边空白cellSpacing/2
final double cellSpacing;
//设置不同列的宽度
final double Function(int columnIndex) columnWidth;
//表格头的背景颜色
final Color headerColor;
final TextStyle headerTextStyle;
//表格内容的颜色交替
final List<Color> cellAlternateColor;
//表格内容的字体颜色
final TextStyle cellTextStyle;
//是否显示网格线
final bool showBorderLine;
//网格线颜色
final Color borderColor;
EnhanceDataTable({
this.fixedFirstRow = false,
this.fixedFirstCol = false,
@required this.rowsCells,
@required this.columnWidth,
this.cellBuilder,
this.cellHeight = 56.0,
this.cellSpacing = 10.0,
this.headerColor,
this.cellAlternateColor,
this.headerTextStyle,
this.cellTextStyle,
this.showBorderLine = true,
this.borderColor,
}) : assert(cellAlternateColor == null || cellAlternateColor.length == 2),
assert(borderColor == null || showBorderLine);
@override
State<StatefulWidget> createState() => EnhanceDataTableState();
}
注意到一开始的import
:
1
2
3
import 'package:flutter/material.dart'
hide DataTable, DataColumn, DataRow, DataCell;
import 'data_table.dart';
首先,是移除掉原生DataTable
相关控件,然后,使用我们自己的data_table.dart
文件。这个是将源码文件data_table.dart
拷贝到本地,并修复了上面说的bug。