How to determine currently visible rows?
Hi!
I have an SfDataGrid with lots of rows that have dynamic heights. I want to be able to determine what are the rows in my datasource that are currently visible, and when the vertical scrollbar changes I want to be notified of such changes.
The docs have an example of how to listen to vertical scrollbar changes (link), but it's not obvious how to convert from a vertical scrollbar position to the rows in the data source that are currently visible.
Any ideas?
Thanks
Hi KD,
At the moment, DataGrid does not have built-in support for obtaining the rows that are currently visible in the view. However, you can achieve your requirement by implementing a workaround. Based on the details you have provided, it seems that you have set dynamic heights for the rows using the onQueryRowHeight callback. In order to determine the visible rows, you can map the row heights with their respective indices in the collection.
To obtain the start index of the visible rows, you can calculate the cumulative sum of the row heights until it reaches the current offset of the verticalScrollController. This will give you the starting index. Similarly, to obtain the end index of the visible rows, you can calculate the cumulative sum of the row heights until it reaches the addition of the current offset of the verticalScrollController and the height of the DataGrid view. Please check the following code snippet for more information.
|
ScrollController scrollController = ScrollController();
// map to store the row heights for each row index Map<int, double> rowHeights = {};
// list to store the rows in view List<DataGridRow> rowsInView = [];
// height of the datagrid double dataGridViewHeight = 500;
@override void initState() { super.initState(); _employees = getEmployeeData(); _employeeDataSource = EmployeeDataSource(_employees);
scrollController.addListener(() { var scrollOffset = scrollController.offset;
double cumulativeOffset = 0.0; int startIndex = -1; int endIndex = -1;
for (int i = 0; i <= rowHeights.length; i++) { cumulativeOffset += rowHeights[i] ?? 0.0; if (startIndex == -1 && cumulativeOffset > scrollOffset) { startIndex = i; } if (cumulativeOffset > scrollOffset && cumulativeOffset <= scrollOffset + dataGridViewHeight) { endIndex = i; }
if (cumulativeOffset > scrollOffset + dataGridViewHeight) { break; } }
rowsInView.clear(); rowsInView = _employeeDataSource.effectiveRows .getRange(startIndex - 1, endIndex) .toList(); }); }
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Flutter SfDataGrid')), body: Card( margin: const EdgeInsets.all(20), child: SizedBox( height: dataGridViewHeight, child: SfDataGrid( source: _employeeDataSource, onQueryRowHeight: (details) { if (details.rowIndex != 0) { if (details.rowIndex % 2 == 0) { rowHeights.addAll({details.rowIndex: 100.0});
return 100; } else { rowHeights.addAll({details.rowIndex: 50.0});
return 50; } } else { return details.rowHeight; } }, verticalScrollController: scrollController, columns: getColumns, columnWidthMode: ColumnWidthMode.fill, ), ), ), ); } |
Regards,
Tamilarasan
Thanks for the response. Is there any consideration for an enhancement that would expose the visible row information from the internal state of the data grid instead? The method above is very slow for large lists as you scroll towards the bottom of the list, it needs further adaptation if the data source of the grid changes dynamically, and the internal data grid state actually already knows visible row information. So it would really be much simpler if there wasa callback that changed when visible row information changed. I could submit a PR for that if it would help. Thanks.
KD,
As we said earlier, Flutter SfDataGrid does not have support for getting
the visible rows. We have considered your request as an enhancement. We will
implement this feature in any of our upcoming releases.
At the planning stage for every release cycle, we review all open features and identify features for implementation based on specific parameters including product vision, technological feasibility, and customer interest. We will let you know when this feature is implemented. We appreciate your patience until then.
Thank you for requesting this feature and helping us define it. We are always trying to make our products better and feature requests like yours are a key part of our product growth efforts.
You can also communicate with us regarding the open features any time using our Feature Report page.
Feedback link: https://www.syncfusion.com/feedback/44216/support-to-get-the-visible-rows-in-the-view
If you have any more specification/suggestions to the feature request, you can add it as a comment in the portal and cast your vote to make it count.
I've implemented a pull request that will implement the feature request here:
https://github.com/syncfusion/flutter-widgets/pull/1377
With this enhancement, it's now easy to get the visible row info whenever the vertical scroll position changes (put code into the initState method of a stateful widget that contains the SfDataGrid):
verticalScrollController.addListener(() {
// NOTE: we use a post-frame callback to ensure we get accurate info after all layout info has been calculated
WidgetsBinding.instance.addPostFrameCallback((_) {
if (context.mounted) {
// NOTE: controller is a DataGridController in this widget's state
final range = controller.visibleBodyRowsRange;
print("DEBUG: VISIBLE ROWS RANGE: ${range?.start} - ${range?.end}");
}
});
});
KD,
Thank you for your interest in Syncfusion Flutter DataGrid. We are pleased to
inform you that we have scheduled the implementation of this feature for our
upcoming 2023 Volume 4 release, expected in mid-December 2023.
We value your input and will certainly take your specific implementation requirements into consideration while developing this feature. As we work on its implementation, we also need to ensure compatibility with other use cases.
We will promptly notify you as soon as this feature is fully implemented and available for use. We sincerely appreciate your patience and understanding in the meantime.
Regards,
Tamilarasan
Hi KD,
We are glad to announce that our Essential Studio 2023 Volume 4 Main Release
V24.1.41 is rolled out and is available for download under the following link.
We are also glad to announce that support for "Retrieving the indices of visible rows and columns" has been incorporated into our 2023 Volume 4 Main Release. Please update the DataGrid package to version 24.1.41.
Code snippet for getting the visible rows:
|
DataGridController dataGridController = DataGridController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Syncfusion DataGrid Demo')), body: Column( children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 10), child: ElevatedButton( onPressed: () { int? startRowIndex = dataGridController .getVisibleRowStartIndex(RowRegion.body); int? endRowIndex = dataGridController.getVisibleRowEndIndex(RowRegion.body); List if (startRowIndex != null && endRowIndex != null) { // Here, we are subtracting 1 because the row index starts from 0. // 1 is the header row count in this DataGrid. visibleRows = _employeeDataSource.effectiveRows .getRange(startRowIndex - 1, endRowIndex) .toList(); } for (var data in visibleRows) { print(data.getCells()[0].value); } }, child: const Text('Get Visible Rows')), ), Expanded( child: SfDataGrid( source: _employeeDataSource, controller: dataGridController, allowSorting: true, columns: getColumns, columnWidthMode: ColumnWidthMode.fill, ), ), ], ), ); } |
UG documentation: https://help.syncfusion.com/flutter/datagrid/scrolling#retrieve-the-indices-of-visible-rows-and-columns
We thank you for your support and appreciate your patience in waiting for this release. Please get in touch with us if you would require any further assistance.
Regards,
Tamilarasan
- 6 Replies
- 2 Participants
-
KD KD
- May 26, 2023 04:46 AM UTC
- Jan 2, 2024 02:20 PM UTC