Unverified Commit d907a262 authored by Ben Konyi's avatar Ben Konyi Committed by GitHub

Fixed issue where PaginatedDataTable would not fill the width of its containing Card (#48531)

parent 31f399f9
......@@ -426,75 +426,82 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
]);
// CARD
return Card(
semanticContainer: false,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Semantics(
container: true,
child: DefaultTextStyle(
// These typographic styles aren't quite the regular ones. We pick the closest ones from the regular
// list and then tweak them appropriately.
// See https://material.io/design/components/data-tables.html#tables-within-cards
style: _selectedRowCount > 0 ? themeData.textTheme.subhead.copyWith(color: themeData.accentColor)
: themeData.textTheme.title.copyWith(fontWeight: FontWeight.w400),
child: IconTheme.merge(
data: const IconThemeData(
opacity: 0.54
),
child: Ink(
height: 64.0,
color: _selectedRowCount > 0 ? themeData.secondaryHeaderColor : null,
child: Padding(
padding: EdgeInsetsDirectional.only(start: startPadding, end: 14.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: headerWidgets,
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Card(
semanticContainer: false,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Semantics(
container: true,
child: DefaultTextStyle(
// These typographic styles aren't quite the regular ones. We pick the closest ones from the regular
// list and then tweak them appropriately.
// See https://material.io/design/components/data-tables.html#tables-within-cards
style: _selectedRowCount > 0 ? themeData.textTheme.subhead.copyWith(color: themeData.accentColor)
: themeData.textTheme.title.copyWith(fontWeight: FontWeight.w400),
child: IconTheme.merge(
data: const IconThemeData(
opacity: 0.54
),
child: Ink(
height: 64.0,
color: _selectedRowCount > 0 ? themeData.secondaryHeaderColor : null,
child: Padding(
padding: EdgeInsetsDirectional.only(start: startPadding, end: 14.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: headerWidgets,
),
),
),
),
),
),
),
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
dragStartBehavior: widget.dragStartBehavior,
child: DataTable(
key: _tableKey,
columns: widget.columns,
sortColumnIndex: widget.sortColumnIndex,
sortAscending: widget.sortAscending,
onSelectAll: widget.onSelectAll,
dataRowHeight: widget.dataRowHeight,
headingRowHeight: widget.headingRowHeight,
horizontalMargin: widget.horizontalMargin,
columnSpacing: widget.columnSpacing,
showCheckboxColumn: widget.showCheckboxColumn,
rows: _getRows(_firstRowIndex, widget.rowsPerPage),
),
),
DefaultTextStyle(
style: footerTextStyle,
child: IconTheme.merge(
data: const IconThemeData(
opacity: 0.54
SingleChildScrollView(
scrollDirection: Axis.horizontal,
dragStartBehavior: widget.dragStartBehavior,
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: constraints.minWidth),
child: DataTable(
key: _tableKey,
columns: widget.columns,
sortColumnIndex: widget.sortColumnIndex,
sortAscending: widget.sortAscending,
onSelectAll: widget.onSelectAll,
dataRowHeight: widget.dataRowHeight,
headingRowHeight: widget.headingRowHeight,
horizontalMargin: widget.horizontalMargin,
columnSpacing: widget.columnSpacing,
rows: _getRows(_firstRowIndex, widget.rowsPerPage),
),
),
),
child: Container(
height: 56.0,
child: SingleChildScrollView(
dragStartBehavior: widget.dragStartBehavior,
scrollDirection: Axis.horizontal,
reverse: true,
child: Row(
children: footerWidgets,
DefaultTextStyle(
style: footerTextStyle,
child: IconTheme.merge(
data: const IconThemeData(
opacity: 0.54
),
child: Container(
// TODO(bkonyi): this won't handle text zoom correctly, https://github.com/flutter/flutter/issues/48522
height: 56.0,
child: SingleChildScrollView(
dragStartBehavior: widget.dragStartBehavior,
scrollDirection: Axis.horizontal,
reverse: true,
child: Row(
children: footerWidgets,
),
),
),
),
),
),
],
),
],
),
);
},
);
}
}
......@@ -50,6 +50,9 @@ class TestDataSource extends DataTableSource {
}
void main() {
final TestWidgetsFlutterBinding binding =
TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
testWidgets('PaginatedDataTable paging', (WidgetTester tester) async {
final TestDataSource source = TestDataSource();
......@@ -382,6 +385,16 @@ void main() {
const double _defaultColumnSpacing = 56.0;
const double _customHorizontalMargin = 10.0;
const double _customColumnSpacing = 15.0;
const double _width = 400;
const double _height = 400;
final Size originalSize = binding.renderView.size;
// Ensure the containing Card is small enough that we don't expand too
// much, resulting in our custom margin being ignored.
await binding.setSurfaceSize(const Size(_width, _height));
final TestDataSource source = TestDataSource(
onSelectChanged: (bool value) {},
);
......@@ -527,6 +540,9 @@ void main() {
tester.getRect(padding).right - tester.getRect(cellContent).right,
_customHorizontalMargin,
);
// Reset the surface size.
await binding.setSurfaceSize(originalSize);
});
testWidgets('PaginatedDataTable custom horizontal padding - no checkbox', (WidgetTester tester) async {
......@@ -651,4 +667,63 @@ void main() {
_customHorizontalMargin,
);
});
testWidgets('PaginatedDataTable table fills Card width', (WidgetTester tester) async {
final TestDataSource source = TestDataSource();
// Note: 800 is wide enough to ensure that all of the columns fit in the
// Card. The DataTable can be larger than its containing Card, but this test
// is only concerned with ensuring the DataTable is at least as wide as the
// Card.
const double _originalWidth = 800;
const double _expandedWidth = 1600;
const double _height = 400;
final Size originalSize = binding.renderView.size;
Widget buildWidget() => MaterialApp(
home: PaginatedDataTable(
header: const Text('Test table'),
source: source,
rowsPerPage: 2,
availableRowsPerPage: const <int>[
2, 4, 8, 16,
],
onRowsPerPageChanged: (int rowsPerPage) {},
onPageChanged: (int rowIndex) {},
columns: const <DataColumn>[
DataColumn(label: Text('Name')),
DataColumn(label: Text('Calories'), numeric: true),
DataColumn(label: Text('Generation')),
],
),
);
await binding.setSurfaceSize(const Size(_originalWidth, _height));
await tester.pumpWidget(buildWidget());
// Widths should be equal before we resize...
expect(
tester.renderObject<RenderBox>(find.byType(DataTable).first).size.width,
moreOrLessEquals(
tester.renderObject<RenderBox>(find.byType(Card).first).size.width)
);
await binding.setSurfaceSize(const Size(_expandedWidth, _height));
await tester.pumpWidget(buildWidget());
final double cardWidth = tester.renderObject<RenderBox>(find.byType(Card).first).size.width;
// ... and should still be equal after the resize.
expect(
tester.renderObject<RenderBox>(find.byType(DataTable).first).size.width,
moreOrLessEquals(cardWidth)
);
// Double check to ensure we actually resized the surface properly.
expect(cardWidth, moreOrLessEquals(_expandedWidth));
// Reset the surface size.
await binding.setSurfaceSize(originalSize);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment