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.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 {
|
|||||||
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 {
|
|||||||
/// 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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
/// 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> {
|
|||||||
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() {
|
|||||||
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(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user