build method
Describes the part of the UI represented by this widget.
Implementation
@override
Widget build(BuildContext context) {
final theme = ThemeScope.of(context);
final bColor = borderColor ?? theme.border;
final hStyle = copyStyle(headerStyle ?? theme.titleSmall)
..foreground(theme.onSurface)
..bold();
final cStyle = copyStyle(cellStyle ?? theme.bodyMedium)
..foreground(theme.onSurface);
final bStyle = copyStyle(Style())..foreground(bColor);
// Calculate column widths.
final colCount = columns.length;
final widths = List<int>.filled(colCount, 0);
_measureCells(_headerCells, widths);
for (final row in _cellRows) {
_measureCells(row, widths);
}
_expandWidthsForSpans(_headerCells, widths);
for (final row in _cellRows) {
_expandWidthsForSpans(row, widths);
}
final chars = _borderChars();
final hasOuterBorder = chars.topLeft != null;
// Build a horizontal rule line.
String buildHRule(String h, String cross, String? left, String? right) {
final parts = <String>[];
if (left != null) parts.add('$left$h');
for (var i = 0; i < colCount; i++) {
parts.add(h * widths[i]);
if (i < colCount - 1) {
parts.add('$h$cross$h');
}
}
if (right != null) parts.add('$h$right');
return parts.join();
}
// Build a content row (header or data).
Widget buildRow(List<DataTableCell> values, Style textStyle) {
final cells = <Widget>[];
if (hasOuterBorder) {
cells.add(Text('${chars.v} ', style: bStyle));
}
var column = 0;
var cellIndex = 0;
while (column < colCount) {
final cell = cellIndex < values.length
? values[cellIndex]
: const DataTableCell('');
final span = cell.columnSpan.clamp(1, colCount - column);
final width = _spannedWidth(widths, column, span);
final value = _align(cell.value, width, cell.textAlign);
cells.add(Text(value, style: cell.style ?? textStyle));
column += span;
cellIndex++;
if (column < colCount) {
cells.add(Text(' ${chars.v} ', style: bStyle));
}
}
if (hasOuterBorder) {
cells.add(Text(' ${chars.v}', style: bStyle));
}
return Row(gap: 0, children: cells);
}
final children = <Widget>[];
// Top border (only for styles with outer borders).
if (hasOuterBorder) {
children.add(
Text(
buildHRule(chars.h, chars.topCross!, chars.topLeft, chars.topRight),
style: bStyle,
),
);
}
// Header row.
children.add(buildRow(_headerCells, hStyle));
// Header separator.
children.add(
Text(
buildHRule(
chars.h,
chars.cross,
hasOuterBorder ? chars.leftCross : null,
hasOuterBorder ? chars.rightCross : null,
),
style: bStyle,
),
);
// Data rows.
for (final row in _cellRows) {
children.add(buildRow(row, cStyle));
}
// Bottom border (only for styles with outer borders).
if (hasOuterBorder) {
children.add(
Text(
buildHRule(
chars.h,
chars.bottomCross!,
chars.bottomLeft,
chars.bottomRight,
),
style: bStyle,
),
);
}
return Column(gap: 0, children: children);
}