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

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.
parent c3f590a8
...@@ -330,6 +330,7 @@ class DataTable extends StatelessWidget { ...@@ -330,6 +330,7 @@ class DataTable extends StatelessWidget {
this.headingRowHeight = 56.0, this.headingRowHeight = 56.0,
this.horizontalMargin = 24.0, this.horizontalMargin = 24.0,
this.columnSpacing = 56.0, this.columnSpacing = 56.0,
this.showCheckboxColumn = true,
@required this.rows, @required this.rows,
}) : assert(columns != null), }) : assert(columns != null),
assert(columns.isNotEmpty), assert(columns.isNotEmpty),
...@@ -339,6 +340,7 @@ class DataTable extends StatelessWidget { ...@@ -339,6 +340,7 @@ class DataTable extends StatelessWidget {
assert(headingRowHeight != null), assert(headingRowHeight != null),
assert(horizontalMargin != null), assert(horizontalMargin != null),
assert(columnSpacing != null), assert(columnSpacing != null),
assert(showCheckboxColumn != null),
assert(rows != null), assert(rows != null),
assert(!rows.any((DataRow row) => row.cells.length != columns.length)), assert(!rows.any((DataRow row) => row.cells.length != columns.length)),
_onlyTextColumn = _initOnlyTextColumn(columns), _onlyTextColumn = _initOnlyTextColumn(columns),
...@@ -408,6 +410,17 @@ class DataTable extends StatelessWidget { ...@@ -408,6 +410,17 @@ class DataTable extends StatelessWidget {
/// This value defaults to 56.0 to adhere to the Material Design specifications. /// This value defaults to 56.0 to adhere to the Material Design specifications.
final double columnSpacing; 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 data to show in each row (excluding the row that contains
/// the column headings). /// the column headings).
/// ///
...@@ -608,10 +621,10 @@ class DataTable extends StatelessWidget { ...@@ -608,10 +621,10 @@ class DataTable extends StatelessWidget {
border: Border(bottom: Divider.createBorderSide(context, width: 1.0)), border: Border(bottom: Divider.createBorderSide(context, width: 1.0)),
); );
final bool showCheckboxColumn = rows.any((DataRow row) => row.onSelectChanged != null); final bool displayCheckboxColumn = showCheckboxColumn && rows.any((DataRow row) => row.onSelectChanged != null);
final bool allChecked = showCheckboxColumn && !rows.any((DataRow row) => row.onSelectChanged != null && !row.selected); 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( final List<TableRow> tableRows = List<TableRow>.generate(
rows.length + 1, // the +1 is for the header row rows.length + 1, // the +1 is for the header row
(int index) { (int index) {
...@@ -627,7 +640,7 @@ class DataTable extends StatelessWidget { ...@@ -627,7 +640,7 @@ class DataTable extends StatelessWidget {
int rowIndex; int rowIndex;
int displayColumnIndex = 0; int displayColumnIndex = 0;
if (showCheckboxColumn) { if (displayCheckboxColumn) {
tableColumns[0] = FixedColumnWidth(horizontalMargin + Checkbox.width + horizontalMargin / 2.0); tableColumns[0] = FixedColumnWidth(horizontalMargin + Checkbox.width + horizontalMargin / 2.0);
tableRows[0].children[0] = _buildCheckbox( tableRows[0].children[0] = _buildCheckbox(
color: theme.accentColor, color: theme.accentColor,
...@@ -651,9 +664,9 @@ class DataTable extends StatelessWidget { ...@@ -651,9 +664,9 @@ class DataTable extends StatelessWidget {
final DataColumn column = columns[dataColumnIndex]; final DataColumn column = columns[dataColumnIndex];
double paddingStart; double paddingStart;
if (dataColumnIndex == 0 && showCheckboxColumn) { if (dataColumnIndex == 0 && displayCheckboxColumn) {
paddingStart = horizontalMargin / 2.0; paddingStart = horizontalMargin / 2.0;
} else if (dataColumnIndex == 0 && !showCheckboxColumn) { } else if (dataColumnIndex == 0 && !displayCheckboxColumn) {
paddingStart = horizontalMargin; paddingStart = horizontalMargin;
} else { } else {
paddingStart = columnSpacing / 2.0; paddingStart = columnSpacing / 2.0;
......
...@@ -74,6 +74,7 @@ class PaginatedDataTable extends StatefulWidget { ...@@ -74,6 +74,7 @@ class PaginatedDataTable extends StatefulWidget {
this.headingRowHeight = 56.0, this.headingRowHeight = 56.0,
this.horizontalMargin = 24.0, this.horizontalMargin = 24.0,
this.columnSpacing = 56.0, this.columnSpacing = 56.0,
this.showCheckboxColumn = true,
this.initialFirstRowIndex = 0, this.initialFirstRowIndex = 0,
this.onPageChanged, this.onPageChanged,
this.rowsPerPage = defaultRowsPerPage, this.rowsPerPage = defaultRowsPerPage,
...@@ -91,6 +92,7 @@ class PaginatedDataTable extends StatefulWidget { ...@@ -91,6 +92,7 @@ class PaginatedDataTable extends StatefulWidget {
assert(headingRowHeight != null), assert(headingRowHeight != null),
assert(horizontalMargin != null), assert(horizontalMargin != null),
assert(columnSpacing != null), assert(columnSpacing != null),
assert(showCheckboxColumn != null),
assert(rowsPerPage != null), assert(rowsPerPage != null),
assert(rowsPerPage > 0), assert(rowsPerPage > 0),
assert(() { assert(() {
...@@ -164,6 +166,9 @@ class PaginatedDataTable extends StatefulWidget { ...@@ -164,6 +166,9 @@ class PaginatedDataTable extends StatefulWidget {
/// This value defaults to 56.0 to adhere to the Material Design specifications. /// This value defaults to 56.0 to adhere to the Material Design specifications.
final double columnSpacing; 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. /// The index of the first row to display when the widget is first created.
final int initialFirstRowIndex; final int initialFirstRowIndex;
...@@ -465,6 +470,7 @@ class PaginatedDataTableState extends State<PaginatedDataTable> { ...@@ -465,6 +470,7 @@ class PaginatedDataTableState extends State<PaginatedDataTable> {
headingRowHeight: widget.headingRowHeight, headingRowHeight: widget.headingRowHeight,
horizontalMargin: widget.horizontalMargin, horizontalMargin: widget.horizontalMargin,
columnSpacing: widget.columnSpacing, columnSpacing: widget.columnSpacing,
showCheckboxColumn: widget.showCheckboxColumn,
rows: _getRows(_firstRowIndex, widget.rowsPerPage), rows: _getRows(_firstRowIndex, widget.rowsPerPage),
), ),
), ),
......
...@@ -99,6 +99,72 @@ void main() { ...@@ -99,6 +99,72 @@ void main() {
log.clear(); 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 { testWidgets('DataTable overflow test - header', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
......
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