mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
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:
parent
c3f590a872
commit
a0e5621956
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue