Skip to content

Commit 793569f

Browse files
authored
Add columnWidth Property to DataTable for Customizable Column Widths (flutter#159279)
<!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> After discussing with @Hixie in flutter#51799, this PR has been created to implement the ability to customize column widths in DataTable. This change introduces the `columnWidth` property to `DataColumn`, allowing developers to specify column widths using `TableColumnWidth` within a `DataTable`. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent 6fbfed8 commit 793569f

File tree

2 files changed

+107
-1
lines changed

2 files changed

+107
-1
lines changed

packages/flutter/lib/src/material/data_table.dart

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class DataColumn {
4242
/// Creates the configuration for a column of a [DataTable].
4343
const DataColumn({
4444
required this.label,
45+
this.columnWidth,
4546
this.tooltip,
4647
this.numeric = false,
4748
this.onSort,
@@ -67,6 +68,22 @@ class DataColumn {
6768
/// The label should not include the sort indicator.
6869
final Widget label;
6970

71+
/// How the horizontal extents of this column of the table should be determined.
72+
///
73+
/// The [FixedColumnWidth] class can be used to specify a specific width in
74+
/// pixels. This is the cheapest way to size a table's columns.
75+
///
76+
/// The layout performance of the table depends critically on which column
77+
/// sizing algorithms are used here. In particular, [IntrinsicColumnWidth] is
78+
/// quite expensive because it needs to measure each cell in the column to
79+
/// determine the intrinsic size of the column.
80+
///
81+
/// If this property is `null`, the table applies a default behavior:
82+
/// - If the table has exactly one column identified as the only text column
83+
/// (i.e., all the rest are numeric), that column uses `IntrinsicColumnWidth(flex: 1.0)`.
84+
/// - All other columns use `IntrinsicColumnWidth()`.
85+
final TableColumnWidth? columnWidth;
86+
7087
/// The column heading's tooltip.
7188
///
7289
/// This is a longer description of the column heading, for cases
@@ -1122,11 +1139,14 @@ class DataTable extends StatelessWidget {
11221139
start: paddingStart,
11231140
end: paddingEnd,
11241141
);
1125-
if (dataColumnIndex == _onlyTextColumn) {
1142+
if (column.columnWidth != null) {
1143+
tableColumns[displayColumnIndex] = column.columnWidth!;
1144+
} else if (dataColumnIndex == _onlyTextColumn) {
11261145
tableColumns[displayColumnIndex] = const IntrinsicColumnWidth(flex: 1.0);
11271146
} else {
11281147
tableColumns[displayColumnIndex] = const IntrinsicColumnWidth();
11291148
}
1149+
11301150
final Set<MaterialState> headerStates = <MaterialState>{
11311151
if (column.onSort == null)
11321152
MaterialState.disabled,

packages/flutter/test/material/data_table_test.dart

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2417,6 +2417,92 @@ void main() {
24172417
headerCenter = tester.getCenter(find.text('Header'));
24182418
expect(headerCenter.dx, equals(400));
24192419
});
2420+
2421+
testWidgets('DataTable with custom column widths - checkbox', (WidgetTester tester) async {
2422+
await tester.pumpWidget(
2423+
MaterialApp(
2424+
home: Material(
2425+
child: SizedBox(
2426+
width: 500,
2427+
child: DataTable(
2428+
columns: const <DataColumn>[
2429+
DataColumn(
2430+
label: Text('Flex Numeric'),
2431+
columnWidth: FlexColumnWidth(),
2432+
numeric: true,
2433+
),
2434+
DataColumn(
2435+
label: Text('Numeric'),
2436+
numeric: true,
2437+
),
2438+
DataColumn(
2439+
label: Text('Text'),
2440+
),
2441+
],
2442+
rows: <DataRow>[
2443+
DataRow(
2444+
onSelectChanged: (bool? value) {},
2445+
cells: const <DataCell>[
2446+
DataCell(Text('1')),
2447+
DataCell(Text('1')),
2448+
DataCell(Text('D')),
2449+
],
2450+
),
2451+
],
2452+
),
2453+
),
2454+
),
2455+
)
2456+
);
2457+
2458+
final Table table = tester.widget(find.byType(Table));
2459+
expect(table.columnWidths![0], isA<FixedColumnWidth>()); // Checkbox column
2460+
expect(table.columnWidths![1], const FlexColumnWidth());
2461+
expect(table.columnWidths![2], const IntrinsicColumnWidth());
2462+
expect(table.columnWidths![3], const IntrinsicColumnWidth(flex: 1));
2463+
});
2464+
2465+
testWidgets('DataTable with custom column widths - no checkbox', (WidgetTester tester) async {
2466+
await tester.pumpWidget(
2467+
MaterialApp(
2468+
home: Material(
2469+
child: SizedBox(
2470+
width: 500,
2471+
child: DataTable(
2472+
columns: const <DataColumn>[
2473+
DataColumn(
2474+
label: Text('Flex Numeric'),
2475+
columnWidth: FlexColumnWidth(),
2476+
numeric: true,
2477+
),
2478+
DataColumn(
2479+
label: Text('Numeric'),
2480+
numeric: true,
2481+
),
2482+
DataColumn(
2483+
label: Text('Text'),
2484+
),
2485+
],
2486+
rows: const <DataRow>[
2487+
DataRow(
2488+
cells: <DataCell>[
2489+
DataCell(Text('1')),
2490+
DataCell(Text('1')),
2491+
DataCell(Text('D')),
2492+
],
2493+
),
2494+
],
2495+
),
2496+
),
2497+
),
2498+
)
2499+
);
2500+
2501+
final Table table = tester.widget(find.byType(Table));
2502+
expect(table.columnWidths![0], const FlexColumnWidth());
2503+
expect(table.columnWidths![1], const IntrinsicColumnWidth());
2504+
expect(table.columnWidths![2], const IntrinsicColumnWidth(flex: 1));
2505+
});
24202506
}
24212507

24222508
RenderParagraph _getTextRenderObject(WidgetTester tester, String text) {

0 commit comments

Comments
 (0)