diff --git a/packages/flutter/lib/src/material/data_table.dart b/packages/flutter/lib/src/material/data_table.dart index df8d3b4f34ae6..b09d4dacbb5f1 100644 --- a/packages/flutter/lib/src/material/data_table.dart +++ b/packages/flutter/lib/src/material/data_table.dart @@ -406,6 +406,7 @@ class DataTable extends StatelessWidget { required this.rows, this.checkboxHorizontalMargin, this.border, + this.clipBehavior = Clip.none, }) : assert(columns != null), assert(columns.isNotEmpty), assert(sortColumnIndex == null || (sortColumnIndex >= 0 && sortColumnIndex < columns.length)), @@ -414,6 +415,7 @@ class DataTable extends StatelessWidget { assert(rows != null), assert(!rows.any((DataRow row) => row.cells.length != columns.length)), assert(dividerThickness == null || dividerThickness >= 0), + assert(clipBehavior != null), _onlyTextColumn = _initOnlyTextColumn(columns); /// The configuration and labels for the columns in the table. @@ -638,6 +640,13 @@ class DataTable extends StatelessWidget { /// The style to use when painting the boundary and interior divisions of the table. final TableBorder? border; + /// {@macro flutter.material.Material.clipBehavior} + /// + /// This can be used to clip the content within the border of the [DataTable]. + /// + /// Defaults to [Clip.none], and must not be null. + final Clip clipBehavior; + // Set by the constructor to the index of the only Column that is // non-numeric, if there is exactly one, otherwise null. final int? _onlyTextColumn; @@ -1056,6 +1065,8 @@ class DataTable extends StatelessWidget { decoration: decoration ?? dataTableTheme.decoration ?? theme.dataTableTheme.decoration, child: Material( type: MaterialType.transparency, + borderRadius: border?.borderRadius, + clipBehavior: clipBehavior, child: Table( columnWidths: tableColumns.asMap(), children: tableRows, diff --git a/packages/flutter/lib/src/rendering/table_border.dart b/packages/flutter/lib/src/rendering/table_border.dart index d504bf4a35a83..8897eb9292002 100644 --- a/packages/flutter/lib/src/rendering/table_border.dart +++ b/packages/flutter/lib/src/rendering/table_border.dart @@ -74,6 +74,8 @@ class TableBorder { final BorderSide verticalInside; /// The [BorderRadius] to use when painting the corners of this border. + /// + /// It is also applied to [DataTable]'s [Material]. final BorderRadius borderRadius; /// The widths of the sides of this border represented as an [EdgeInsets]. diff --git a/packages/flutter/test/material/data_table_test.dart b/packages/flutter/test/material/data_table_test.dart index 89758049f9d12..d05ddc092d902 100644 --- a/packages/flutter/test/material/data_table_test.dart +++ b/packages/flutter/test/material/data_table_test.dart @@ -1895,4 +1895,53 @@ void main() { // Go without crashes. }); + + testWidgets('DataTable clip behavior', (WidgetTester tester) async { + const Color selectedColor = Colors.green; + const Color defaultColor = Colors.red; + const BorderRadius borderRadius = BorderRadius.all(Radius.circular(30)); + + Widget buildTable({bool selected = false, required Clip clipBehavior}) { + return Material( + child: DataTable( + clipBehavior: clipBehavior, + border: TableBorder.all(borderRadius: borderRadius), + columns: const [ + DataColumn( + label: Text('Column1'), + ), + ], + rows: [ + DataRow( + selected: selected, + color: MaterialStateProperty.resolveWith( + (Set states) { + if (states.contains(MaterialState.selected)) { + return selectedColor; + } + return defaultColor; + }, + ), + cells: const [ + DataCell(Text('Content1')), + ], + ), + ], + ), + ); + } + + // Test default clip behavior. + await tester.pumpWidget(MaterialApp(home: buildTable(clipBehavior: Clip.none))); + + Material material = tester.widget(find.byType(Material).last); + expect(material.clipBehavior, Clip.none); + expect(material.borderRadius, borderRadius); + + await tester.pumpWidget(MaterialApp(home: buildTable(clipBehavior: Clip.hardEdge))); + + material = tester.widget(find.byType(Material).last); + expect(material.clipBehavior, Clip.hardEdge); + expect(material.borderRadius, borderRadius); + }); }