How to add a DataRow in Flutter?
The following example code shows how you could add to or remove columns from a DataTable
:
class InteractiveDataTable extends StatefulWidget {
@override
State<StatefulWidget> createState() => InteractiveDataTableState();
}
class InteractiveDataTableState extends State<InteractiveDataTable> {
final List<Map<String, String>> _data = [
{'Country': 'China', 'Population': '1400'},
{'Country': 'India', 'Population': '1360'},
];
late List<String> _columnNames;
void _addColumn(String newColumn) {
if (_columnNames.contains(newColumn)) {
return;
}
setState(() {
for (var i = 0; i <= _data.length - 1; i++) {
_data[i][newColumn] = '';
}
_columnNames.add(newColumn);
});
}
void _removeColumn(String oldColumn) {
if (_columnNames.length == 1 || !_columnNames.contains(oldColumn)) {
return;
}
setState(() {
for (var i = 0; i <= _data.length - 1; i++) {
_data[i].remove(oldColumn);
}
_columnNames.remove(oldColumn);
});
}
void _addRow(Map<String, String> newRow) {
_columnNames.forEach((colName) {
if (!newRow.containsKey(colName)) {
newRow[colName] = '';
}
});
setState(() {
_data.add(newRow);
});
}
@override
void initState() {
_columnNames = _data[0].keys.toList();
super.initState();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
ElevatedButton(
onPressed: () => _addRow(
{'Country': 'USA', 'Population': '330'},
),
child: const Text('Add row'),
),
SizedBox(
height: 10,
),
ElevatedButton(
onPressed: () => _addColumn('GDP'),
child: const Text('Add column'),
),
SizedBox(
height: 10,
),
ElevatedButton(
onPressed: () => _removeColumn('GDP'),
child: const Text('Remove column'),
),
DataTable(
columns: _columnNames.map((columnName) {
return DataColumn(
label: Text(
columnName,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
);
}).toList(),
rows: _data.map((row) {
return DataRow(
cells: row.values.map((cellValue) {
return DataCell(
Text(
cellValue,
style: TextStyle(
color: Colors.white,
),
),
);
}).toList());
}).toList(),
),
],
),
);
}
}
If you plan to add more than a dozen rows to your DataTable
, you might encounter performance issues. In such cases, the Flutter team recommends to use the PaginatedDataTable
instead. From the docs:
Displaying data in a table is expensive, because to lay out the table all the data must be measured twice, once to negotiate the dimensions to use for each column, and once to actually lay out the table given the results of the negotiation. For this reason, if you have a lot of data (say, more than a dozen rows with a dozen columns, though the precise limits depend on the target device), it is suggested that you use a PaginatedDataTable which automatically splits the data into multiple pages.
Dalon
Updated on December 30, 2022Comments
-
Dalon about 1 year
I have a
DataTable
where the user can addrows
andcolumns
. The Problem is, that when he add a newcolumn
the rows he can add in future need an extra DataCell so that columns and rows still have the same size. How can I automatically create a DataRow with matching DataCells? So far the function to add Rows is static and when the size of columns change there is an error when i try to add a new Row.List<DataColumn> _columnList = [ DataColumn(label: Text('Datum', style: TextStyle(fontSize: 16))), DataColumn(label: ExerciseName(key: GlobalKey())), DataColumn(label: ExerciseName(key: GlobalKey())), DataColumn(label: Text('Notes', style: TextStyle(fontSize: 16), key: GlobalKey())), ]; List<DataRow> _rowList = [ DataRow(cells: <DataCell>[ DataCell(Datum(key: GlobalKey())), DataCell(ExerciseWidget(key: GlobalKey())), DataCell(ExerciseWidget(key: GlobalKey())), DataCell(Notes(key: GlobalKey())), ]), ]; void _addRow() { _rowList.insert(0, DataRow(cells: <DataCell>[ DataCell(Datum(key: GlobalKey())), DataCell(ExerciseWidget(key: GlobalKey())), DataCell(ExerciseWidget(key: GlobalKey())), DataCell(Notes(key: GlobalKey())), ])); setState(() {}); }