build method
Builds the complete table UI with pinned headers, scrollable rows, and Forui styling.
Layout structure:
- Container with Forui FCard styling (borders, rounded corners, background)
- Column with:
- Pinned header row: Row with all header cells, vertically padded
- Divider: Subtle Forui FDivider separating header from rows
- Scrollable ListView: Rows with item separators (dividers) between each row
Each cell is wrapped in:
- Expanded with flex ratio from columnFlex
- Padding based on density
- Align based on
_getAlignmentresult - Normalized widget from
_normalizeCell
See class documentation for example usage.
Implementation
@override
Widget build(BuildContext context) {
// We fetch the theme configuration to replicate Forui's FCard styling exactly
final theme = FTheme.of(context);
return Container(
constraints: BoxConstraints(maxHeight: height),
// Replicating Forui's FCard aesthetic: clean borders, rounded corners, and background
decoration: theme.cardStyle.decoration,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
// 1. Pinned Header Row
Padding(
padding: EdgeInsets.symmetric(
vertical: density.verticalPadding,
horizontal: density.horizontalPadding,
),
child: Row(
children: List.generate(headers.length, (index) {
return Expanded(
flex: columnFlex[index],
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: density.columnSpacing,
),
child: Align(
alignment: _getAlignment(index),
child: _normalizeCell(headers[index], isHeader: true),
),
),
);
}),
),
),
// Forui native subtle divider line
const FDivider(style: .delta(padding: .value(EdgeInsets.zero))),
// 2. Bound Scrollable Rows Viewport
Flexible(
child: ListView.separated(
shrinkWrap: true,
padding: EdgeInsets.symmetric(vertical: density.verticalPadding),
itemCount: rows.length,
separatorBuilder: (context, index) => FDivider(
style: .delta(
padding: .value(
EdgeInsets.symmetric(vertical: density.verticalPadding),
),
),
),
itemBuilder: (context, rowIndex) {
final rowData = rows[rowIndex];
return Padding(
padding: EdgeInsets.symmetric(
horizontal: density.horizontalPadding,
),
child: Row(
children: List.generate(rowData.length, (colIndex) {
return Expanded(
flex: columnFlex[colIndex],
// Added identical padding to cell body blocks
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: density.columnSpacing,
),
child: Align(
alignment: _getAlignment(colIndex),
child: _normalizeCell(rowData[colIndex]),
),
),
);
}),
),
);
},
),
),
],
),
);
}