Custom height parameters for DataTable header and data rows (#33535)
* Custom dataRowHeight for DataTable and PaginatedDataTable * Custom headingRowHeight for DataTable and PaginatedDataTable
This commit is contained in:
parent
23c25d9e2d
commit
71254a6147
@ -262,6 +262,8 @@ class DataTable extends StatelessWidget {
|
||||
this.sortColumnIndex,
|
||||
this.sortAscending = true,
|
||||
this.onSelectAll,
|
||||
this.dataRowHeight = 48.0,
|
||||
this.headingRowHeight = 56.0,
|
||||
this.horizontalMargin = 24.0,
|
||||
this.columnSpacing = 56.0,
|
||||
@required this.rows,
|
||||
@ -269,6 +271,8 @@ class DataTable extends StatelessWidget {
|
||||
assert(columns.isNotEmpty),
|
||||
assert(sortColumnIndex == null || (sortColumnIndex >= 0 && sortColumnIndex < columns.length)),
|
||||
assert(sortAscending != null),
|
||||
assert(dataRowHeight != null),
|
||||
assert(headingRowHeight != null),
|
||||
assert(horizontalMargin != null),
|
||||
assert(columnSpacing != null),
|
||||
assert(rows != null),
|
||||
@ -315,6 +319,16 @@ class DataTable extends StatelessWidget {
|
||||
/// row is selectable.
|
||||
final ValueSetter<bool> onSelectAll;
|
||||
|
||||
/// The height of each row (excluding the row that contains column headings).
|
||||
///
|
||||
/// This value defaults to 48.0 to adhere to the Material Design specifications.
|
||||
final double dataRowHeight;
|
||||
|
||||
/// The height of the heading row.
|
||||
///
|
||||
/// This value defaults to 56.0 to adhere to the Material Design specifications.
|
||||
final double headingRowHeight;
|
||||
|
||||
/// The horizontal margin between the edges of the table and the content
|
||||
/// in the first and last cells of each row.
|
||||
///
|
||||
@ -330,7 +344,9 @@ class DataTable extends StatelessWidget {
|
||||
final double columnSpacing;
|
||||
|
||||
/// The data to show in each row (excluding the row that contains
|
||||
/// the column headings). Must be non-null, but may be empty.
|
||||
/// the column headings).
|
||||
///
|
||||
/// Must be non-null, but may be empty.
|
||||
final List<DataRow> rows;
|
||||
|
||||
// Set by the constructor to the index of the only Column that is
|
||||
@ -367,8 +383,6 @@ class DataTable extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
static const double _headingRowHeight = 56.0;
|
||||
static const double _dataRowHeight = 48.0;
|
||||
static const double _sortArrowPadding = 2.0;
|
||||
static const double _headingFontSize = 12.0;
|
||||
static const Duration _sortArrowAnimationDuration = Duration(milliseconds: 150);
|
||||
@ -430,14 +444,14 @@ class DataTable extends StatelessWidget {
|
||||
}
|
||||
label = Container(
|
||||
padding: padding,
|
||||
height: _headingRowHeight,
|
||||
height: headingRowHeight,
|
||||
alignment: numeric ? Alignment.centerRight : AlignmentDirectional.centerStart,
|
||||
child: AnimatedDefaultTextStyle(
|
||||
style: TextStyle(
|
||||
// TODO(ianh): font family should match Theme; see https://github.com/flutter/flutter/issues/3116
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: _headingFontSize,
|
||||
height: math.min(1.0, _headingRowHeight / _headingFontSize),
|
||||
height: math.min(1.0, headingRowHeight / _headingFontSize),
|
||||
color: (Theme.of(context).brightness == Brightness.light)
|
||||
? ((onSort != null && sorted) ? Colors.black87 : Colors.black54)
|
||||
: ((onSort != null && sorted) ? Colors.white : Colors.white70),
|
||||
@ -483,7 +497,7 @@ class DataTable extends StatelessWidget {
|
||||
}
|
||||
label = Container(
|
||||
padding: padding,
|
||||
height: _dataRowHeight,
|
||||
height: dataRowHeight,
|
||||
alignment: numeric ? Alignment.centerRight : AlignmentDirectional.centerStart,
|
||||
child: DefaultTextStyle(
|
||||
style: TextStyle(
|
||||
|
@ -70,6 +70,8 @@ class PaginatedDataTable extends StatefulWidget {
|
||||
this.sortColumnIndex,
|
||||
this.sortAscending = true,
|
||||
this.onSelectAll,
|
||||
this.dataRowHeight = 48.0,
|
||||
this.headingRowHeight = 56.0,
|
||||
this.horizontalMargin = 24.0,
|
||||
this.columnSpacing = 56.0,
|
||||
this.initialFirstRowIndex = 0,
|
||||
@ -85,6 +87,8 @@ class PaginatedDataTable extends StatefulWidget {
|
||||
assert(columns.isNotEmpty),
|
||||
assert(sortColumnIndex == null || (sortColumnIndex >= 0 && sortColumnIndex < columns.length)),
|
||||
assert(sortAscending != null),
|
||||
assert(dataRowHeight != null),
|
||||
assert(headingRowHeight != null),
|
||||
assert(horizontalMargin != null),
|
||||
assert(columnSpacing != null),
|
||||
assert(rowsPerPage != null),
|
||||
@ -135,6 +139,16 @@ class PaginatedDataTable extends StatefulWidget {
|
||||
/// See [DataTable.onSelectAll].
|
||||
final ValueSetter<bool> onSelectAll;
|
||||
|
||||
/// The height of each row (excluding the row that contains column headings).
|
||||
///
|
||||
/// This value is optional and defaults to 48.0 if not specified.
|
||||
final double dataRowHeight;
|
||||
|
||||
/// The height of the heading row.
|
||||
///
|
||||
/// This value is optional and defaults to 56.0 if not specified.
|
||||
final double headingRowHeight;
|
||||
|
||||
/// The horizontal margin between the edges of the table and the content
|
||||
/// in the first and last cells of each row.
|
||||
///
|
||||
@ -448,6 +462,8 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
|
||||
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),
|
||||
|
@ -267,6 +267,123 @@ void main() {
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('DataTable custom row height', (WidgetTester tester) async {
|
||||
Widget buildCustomTable({
|
||||
int sortColumnIndex,
|
||||
bool sortAscending = true,
|
||||
double dataRowHeight = 48.0,
|
||||
double headingRowHeight = 56.0,
|
||||
}) {
|
||||
return DataTable(
|
||||
sortColumnIndex: sortColumnIndex,
|
||||
sortAscending: sortAscending,
|
||||
onSelectAll: (bool value) {},
|
||||
dataRowHeight: dataRowHeight,
|
||||
headingRowHeight: headingRowHeight,
|
||||
columns: <DataColumn>[
|
||||
const DataColumn(
|
||||
label: Text('Name'),
|
||||
tooltip: 'Name',
|
||||
),
|
||||
DataColumn(
|
||||
label: const Text('Calories'),
|
||||
tooltip: 'Calories',
|
||||
numeric: true,
|
||||
onSort: (int columnIndex, bool ascending) {},
|
||||
),
|
||||
],
|
||||
rows: kDesserts.map<DataRow>((Dessert dessert) {
|
||||
return DataRow(
|
||||
key: Key(dessert.name),
|
||||
onSelectChanged: (bool selected) {},
|
||||
cells: <DataCell>[
|
||||
DataCell(
|
||||
Text(dessert.name),
|
||||
),
|
||||
DataCell(
|
||||
Text('${dessert.calories}'),
|
||||
showEditIcon: true,
|
||||
onTap: () {},
|
||||
),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
// DEFAULT VALUES
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(
|
||||
child: DataTable(
|
||||
onSelectAll: (bool value) {},
|
||||
columns: <DataColumn>[
|
||||
const DataColumn(
|
||||
label: Text('Name'),
|
||||
tooltip: 'Name',
|
||||
),
|
||||
DataColumn(
|
||||
label: const Text('Calories'),
|
||||
tooltip: 'Calories',
|
||||
numeric: true,
|
||||
onSort: (int columnIndex, bool ascending) {},
|
||||
),
|
||||
],
|
||||
rows: kDesserts.map<DataRow>((Dessert dessert) {
|
||||
return DataRow(
|
||||
key: Key(dessert.name),
|
||||
onSelectChanged: (bool selected) {},
|
||||
cells: <DataCell>[
|
||||
DataCell(
|
||||
Text(dessert.name),
|
||||
),
|
||||
DataCell(
|
||||
Text('${dessert.calories}'),
|
||||
showEditIcon: true,
|
||||
onTap: () {},
|
||||
),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(
|
||||
find.widgetWithText(Container, 'Name')
|
||||
).size.height, 56.0); // This is the header row height
|
||||
expect(tester.renderObject<RenderBox>(
|
||||
find.widgetWithText(Container, 'Frozen yogurt')
|
||||
).size.height, 48.0); // This is the data row height
|
||||
|
||||
// CUSTOM VALUES
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(child: buildCustomTable(headingRowHeight: 48.0)),
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(
|
||||
find.widgetWithText(Container, 'Name')
|
||||
).size.height, 48.0);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(child: buildCustomTable(headingRowHeight: 64.0)),
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(
|
||||
find.widgetWithText(Container, 'Name')
|
||||
).size.height, 64.0);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(child: buildCustomTable(dataRowHeight: 30.0)),
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(
|
||||
find.widgetWithText(Container, 'Frozen yogurt')
|
||||
).size.height, 30.0);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(child: buildCustomTable(dataRowHeight: 56.0)),
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(
|
||||
find.widgetWithText(Container, 'Frozen yogurt')
|
||||
).size.height, 56.0);
|
||||
});
|
||||
|
||||
testWidgets('DataTable custom horizontal padding - checkbox', (WidgetTester tester) async {
|
||||
const double _defaultHorizontalMargin = 24.0;
|
||||
const double _defaultColumnSpacing = 56.0;
|
||||
|
@ -296,6 +296,86 @@ void main() {
|
||||
expect(find.text('Rows per page:'), findsOneWidget);
|
||||
expect(tester.getTopLeft(find.text('Rows per page:')).dx, 18.0); // 14 padding in the footer row, 4 padding from the card
|
||||
});
|
||||
testWidgets('PaginatedDataTable custom row height', (WidgetTester tester) async {
|
||||
final TestDataSource source = TestDataSource();
|
||||
|
||||
Widget buildCustomHeightPaginatedTable({
|
||||
double dataRowHeight = 48.0,
|
||||
double headingRowHeight = 56.0,
|
||||
}) {
|
||||
return 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')),
|
||||
],
|
||||
dataRowHeight: dataRowHeight,
|
||||
headingRowHeight: headingRowHeight,
|
||||
);
|
||||
}
|
||||
|
||||
// DEFAULT VALUES
|
||||
await tester.pumpWidget(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')),
|
||||
],
|
||||
),
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(
|
||||
find.widgetWithText(Container, 'Name').first
|
||||
).size.height, 56.0); // This is the header row height
|
||||
expect(tester.renderObject<RenderBox>(
|
||||
find.widgetWithText(Container, 'Frozen yogurt (0)').first
|
||||
).size.height, 48.0); // This is the data row height
|
||||
|
||||
// CUSTOM VALUES
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(child: buildCustomHeightPaginatedTable(headingRowHeight: 48.0)),
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(
|
||||
find.widgetWithText(Container, 'Name').first
|
||||
).size.height, 48.0);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(child: buildCustomHeightPaginatedTable(headingRowHeight: 64.0)),
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(
|
||||
find.widgetWithText(Container, 'Name').first
|
||||
).size.height, 64.0);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(child: buildCustomHeightPaginatedTable(dataRowHeight: 30.0)),
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(
|
||||
find.widgetWithText(Container, 'Frozen yogurt (0)').first
|
||||
).size.height, 30.0);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(child: buildCustomHeightPaginatedTable(dataRowHeight: 56.0)),
|
||||
));
|
||||
expect(tester.renderObject<RenderBox>(
|
||||
find.widgetWithText(Container, 'Frozen yogurt (0)').first
|
||||
).size.height, 56.0);
|
||||
});
|
||||
|
||||
testWidgets('PaginatedDataTable custom horizontal padding - checkbox', (WidgetTester tester) async {
|
||||
const double _defaultHorizontalMargin = 24.0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user