Added showCheckboxColumn parameter to DataTable and PaginatedDataTable (#47552)

`showCheckboxColumn` will determine whether or not selectable rows in
DateTable or PaginatedDataTable will contain a leading CheckBox.
This commit is contained in:
Ben Konyi 2020-01-06 16:29:36 -05:00 committed by GitHub
parent c3f590a872
commit a0e5621956
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 91 additions and 6 deletions

View file

@ -330,6 +330,7 @@ class DataTable extends StatelessWidget {
this.headingRowHeight = 56.0,
this.horizontalMargin = 24.0,
this.columnSpacing = 56.0,
this.showCheckboxColumn = true,
@required this.rows,
}) : assert(columns != null),
assert(columns.isNotEmpty),
@ -339,6 +340,7 @@ class DataTable extends StatelessWidget {
assert(headingRowHeight != null),
assert(horizontalMargin != null),
assert(columnSpacing != null),
assert(showCheckboxColumn != null),
assert(rows != null),
assert(!rows.any((DataRow row) => row.cells.length != columns.length)),
_onlyTextColumn = _initOnlyTextColumn(columns),
@ -408,6 +410,17 @@ class DataTable extends StatelessWidget {
/// This value defaults to 56.0 to adhere to the Material Design specifications.
final double columnSpacing;
/// {@template flutter.material.dataTable.showCheckboxColumn}
/// Whether the widget should display checkboxes for selectable rows.
///
/// If true, a [CheckBox] will be placed at the beginning of each row that is
/// selectable. However, if [DataRow.onSelectChanged] is not set for any row,
/// checkboxes will not be placed, even if this value is true.
///
/// If false, all rows will not display a [CheckBox].
/// {@endtemplate}
final bool showCheckboxColumn;
/// The data to show in each row (excluding the row that contains
/// the column headings).
///
@ -608,10 +621,10 @@ class DataTable extends StatelessWidget {
border: Border(bottom: Divider.createBorderSide(context, width: 1.0)),
);
final bool showCheckboxColumn = rows.any((DataRow row) => row.onSelectChanged != null);
final bool allChecked = showCheckboxColumn && !rows.any((DataRow row) => row.onSelectChanged != null && !row.selected);
final bool displayCheckboxColumn = showCheckboxColumn && rows.any((DataRow row) => row.onSelectChanged != null);
final bool allChecked = displayCheckboxColumn && !rows.any((DataRow row) => row.onSelectChanged != null && !row.selected);
final List<TableColumnWidth> tableColumns = List<TableColumnWidth>(columns.length + (showCheckboxColumn ? 1 : 0));
final List<TableColumnWidth> tableColumns = List<TableColumnWidth>(columns.length + (displayCheckboxColumn ? 1 : 0));
final List<TableRow> tableRows = List<TableRow>.generate(
rows.length + 1, // the +1 is for the header row
(int index) {
@ -627,7 +640,7 @@ class DataTable extends StatelessWidget {
int rowIndex;
int displayColumnIndex = 0;
if (showCheckboxColumn) {
if (displayCheckboxColumn) {
tableColumns[0] = FixedColumnWidth(horizontalMargin + Checkbox.width + horizontalMargin / 2.0);
tableRows[0].children[0] = _buildCheckbox(
color: theme.accentColor,
@ -651,9 +664,9 @@ class DataTable extends StatelessWidget {
final DataColumn column = columns[dataColumnIndex];
double paddingStart;
if (dataColumnIndex == 0 && showCheckboxColumn) {
if (dataColumnIndex == 0 && displayCheckboxColumn) {
paddingStart = horizontalMargin / 2.0;
} else if (dataColumnIndex == 0 && !showCheckboxColumn) {
} else if (dataColumnIndex == 0 && !displayCheckboxColumn) {
paddingStart = horizontalMargin;
} else {
paddingStart = columnSpacing / 2.0;

View file

@ -74,6 +74,7 @@ class PaginatedDataTable extends StatefulWidget {
this.headingRowHeight = 56.0,
this.horizontalMargin = 24.0,
this.columnSpacing = 56.0,
this.showCheckboxColumn = true,
this.initialFirstRowIndex = 0,
this.onPageChanged,
this.rowsPerPage = defaultRowsPerPage,
@ -91,6 +92,7 @@ class PaginatedDataTable extends StatefulWidget {
assert(headingRowHeight != null),
assert(horizontalMargin != null),
assert(columnSpacing != null),
assert(showCheckboxColumn != null),
assert(rowsPerPage != null),
assert(rowsPerPage > 0),
assert(() {
@ -164,6 +166,9 @@ class PaginatedDataTable extends StatefulWidget {
/// This value defaults to 56.0 to adhere to the Material Design specifications.
final double columnSpacing;
/// {@macro flutter.material.dataTable.showCheckboxColumn}
final bool showCheckboxColumn;
/// The index of the first row to display when the widget is first created.
final int initialFirstRowIndex;
@ -465,6 +470,7 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
headingRowHeight: widget.headingRowHeight,
horizontalMargin: widget.horizontalMargin,
columnSpacing: widget.columnSpacing,
showCheckboxColumn: widget.showCheckboxColumn,
rows: _getRows(_firstRowIndex, widget.rowsPerPage),
),
),

View file

@ -99,6 +99,72 @@ void main() {
log.clear();
});
testWidgets('DataTable control test - no checkboxes', (WidgetTester tester) async {
final List<String> log = <String>[];
Widget buildTable({ bool checkboxes = false }) {
return DataTable(
showCheckboxColumn: checkboxes,
onSelectAll: (bool value) {
log.add('select-all: $value');
},
columns: const <DataColumn>[
DataColumn(
label: Text('Name'),
tooltip: 'Name',
),
DataColumn(
label: Text('Calories'),
tooltip: 'Calories',
numeric: true,
),
],
rows: kDesserts.map<DataRow>((Dessert dessert) {
return DataRow(
key: ValueKey<String>(dessert.name),
onSelectChanged: (bool selected) {
log.add('row-selected: ${dessert.name}');
},
cells: <DataCell>[
DataCell(
Text(dessert.name),
),
DataCell(
Text('${dessert.calories}'),
showEditIcon: true,
onTap: () {
log.add('cell-tap: ${dessert.calories}');
},
),
],
);
}).toList(),
);
}
await tester.pumpWidget(MaterialApp(
home: Material(child: buildTable()),
));
expect(find.byType(Checkbox), findsNothing);
await tester.tap(find.text('Cupcake'));
expect(log, <String>['row-selected: Cupcake']);
log.clear();
await tester.pumpWidget(MaterialApp(
home: Material(child: buildTable(checkboxes: true)),
));
await tester.pumpAndSettle(const Duration(milliseconds: 200));
final Finder checkboxes = find.byType(Checkbox);
expect(checkboxes, findsNWidgets(11));
await tester.tap(checkboxes.first);
expect(log, <String>['select-all: true']);
log.clear();
});
testWidgets('DataTable overflow test - header', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(