Reputation: 1295
I have a data table that scrolls horizontally and vertically due to the amount of data available. I want the top row which specifies the column names to always be visible when scrolling down.
code: No issues in the code I am getting the results, but when I scroll down The header wont be shown. Can any one help me in how to fix the header(1st row).
My header(1st row) elements keeps changing for each req, the way its implemented is there will be cards in my dashboard onclicking each card it hits the API and I am displaying its result i.e contents of field named header list as my first row.
Content of the header keeps changing for each card. so once any card is clicked new page containing its data will popup, there I need to fix the header.
Widget getTable(BuildContext context, var data) {
Widget _widget;
_widget = SingleChildScrollView(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
rows: createDataRows(context, data),
columns: createDataColumns(context, data),
),
),
);
return _widget;
}
List<DataRow> createDataRows(BuildContext context, var jsonData) {
List<DataRow> _dataRows = [];
List<DataCell> _cells = [];
String _dataCellTitle;
Map<String, Object> headers = jsonData['headers'];
Map<int, String> headerMapping;
headerMapping = headers.keys
.toList()
.asMap()
.map((index, value) => MapEntry(index + 1, value));
if (jsonData["data"] == null) {
_dataRows = [];
} else {
for (var j = 0; j < jsonData["data"].length; j++) {
_cells.add(DataCell(Text('${j + 1}')));
for (int i = 1; i <= headerMapping.length; i++) {
_dataCellTitle = "${jsonData["data"][j][headerMapping[i]]}" ?? '-';
_cells.add(DataCell(Text('$_dataCellTitle')));
}
_dataRows.add(DataRow(cells: _cells));
_cells = [];
}
}
return _dataRows;
}
List<DataColumn> createDataColumns(BuildContext context, var jsonData) {
String columnTitle;
List<DataColumn> _dataColumns = [];
Map<String, Object> headers = jsonData['headers'];
Map<int, String> headerMapping;
headerMapping = headers.keys
.toList()
.asMap()
.map((index, value) => MapEntry(index + 1, value));
_dataColumns.add(DataColumn(label: Text('S. No.')));
for (int i = 1; i <= headerMapping.length; i++) {
columnTitle = headers[headerMapping[i]];
_dataColumns.add(
DataColumn(label: Text('$columnTitle')),
);
}
return _dataColumns;
}
like this here
where the first row is constant and first column also.
Upvotes: 5
Views: 8563
Reputation: 11
This is the solution to make Datatable Header sticky :
SizedBox(
height: 500,
width: 1000,
child: Scrollbar(
controller: _vertical,
thumbVisibility: true,
trackVisibility: true,
child: Scrollbar(
controller: _horizontal,
thumbVisibility: true,
trackVisibility: true,
child: SingleChildScrollView(
controller: _horizontal,
scrollDirection: Axis.horizontal,
child: Stack(
children: [
SingleChildScrollView(
controller: _vertical,
scrollDirection: Axis.vertical,
child: DataTable(
rows: list_rows, // PROVIDE ROWS HERE
columns: List.generate(
list_column.length,
(index) => DataColumn(
label: Text(''),
),
), //GENERATE EMPTY COLUMNS
headingRowHeight: 90, // HEADER HEIGHT
),
),
DataTable(
rows: [], // DONT PROVIDE ROWS
columns:
list_column, // PROVIDE YOUR COLUMNS HERE
headingRowHeight: 90, // HEADER HEIGHT
headingRowColor: MaterialStateColor.resolveWith(
(states) => Color.fromRGBO(86, 153, 255, 1),
),
border: TableBorder.all(
width: 1.0, color: Colors.white),
),
],
),
),
),
),
),
Upvotes: 1
Reputation: 353
You can do the smart thing here, You can create two datatables one with only column, and one with rows.
Suppose your list_rows
is a List<DataRow> and list_column
is List<DataColumn> of your actual columns, then:
Column(
children: [
DataTable(
rows: [], // DONT PROVIDE ROWS
columns: list_column, // PROVIDE YOUR COLUMNS HERE
),
Expanded(
child: SingleChildScrollView(
child: DataTable(
rows: list_lows, // PROVIDE ROWS HERE
columns: List.generate(
list_column.length, (index) => DataColumn(label: Text(''))), // GENERATE EMPTY COLUMNS
headingRowHeight: 0, // SHRINK THE HEADER
),
),
),
],
)
This way your columns will always be on top!
Upvotes: 1
Reputation: 4750
I have Used Like that , and its working fine :
SingleChildScrollView dataBody() {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: DataTable(
columnSpacing: 10,
//sortAscending: sort,
//sortColumnIndex: 0,
columns: [
DataColumn(label: Text("Date"), numeric: false),
DataColumn(label: Text("Particulars"), numeric: false),
DataColumn(label: Text("Amount"), numeric: true)
],
rows: transactions
.map((txn) => DataRow(cells: [
DataCell(
Text(
DateFormat('dd-MMM-yyyy').format(txn.date),
style: TextStyle(fontSize: 12.0),
),
/*onTap: () {
print('Selected ${txn.date}');
}*/
),
DataCell(FittedBox(
child: Text(
txn.particulars,
),
)),
DataCell(Text(txn.amount.toString()))
]))
.toList(),
),
));
}
Upvotes: 0
Reputation: 1112
Okay so you have one method getTable
to get data content,
In it you are calling two methods
1) To fetch rows
2) To fetch columns.
But you didn't show the code of DataTable
Widget.
I assume it is ListView or Column.
So in your DataTable Widget you should create one static Row
for that heading.
ListView(
children: <Widget>[
Row(
children: <Widget>[
Text('$heading1'),
Text('$heading2'),
Text('$heading3'),
],
),
/// Your row and column
],
);
With information you provided i assume it will help you out.
Upvotes: 0