[LazyLoadScrollView] Fix callback logic

Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
Sahil Kumar
2020-12-17 14:42:46 +05:30
parent 7fd98111d2
commit e17a3c30b7
2 changed files with 54 additions and 46 deletions
+48 -41
View File
@@ -15,7 +15,7 @@ class LazyLoadScrollView extends StatefulWidget {
/// Called when the [child] reaches the end of the list /// Called when the [child] reaches the end of the list
final AsyncCallback onEndOfPage; final AsyncCallback onEndOfPage;
/// The offset to take into account when triggering [onEndOfPage] in pixels /// The offset to take into account when triggering [onEndOfPage]/[onStartOfPage] in pixels
final double scrollOffset; final double scrollOffset;
/// Used to determine if loading of new data has finished. You should use set this if you aren't using a FutureBuilder or StreamBuilder /// Used to determine if loading of new data has finished. You should use set this if you aren't using a FutureBuilder or StreamBuilder
@@ -38,6 +38,7 @@ class LazyLoadScrollView extends StatefulWidget {
class _LazyLoadScrollViewState extends State<LazyLoadScrollView> { class _LazyLoadScrollViewState extends State<LazyLoadScrollView> {
_LoadingStatus _loadMoreStatus = _LoadingStatus.STABLE; _LoadingStatus _loadMoreStatus = _LoadingStatus.STABLE;
double _scrollPosition = 0.0;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -49,59 +50,65 @@ class _LazyLoadScrollViewState extends State<LazyLoadScrollView> {
bool _onNotification(Notification notification) { bool _onNotification(Notification notification) {
if (notification is ScrollUpdateNotification) { if (notification is ScrollUpdateNotification) {
if (notification.metrics.maxScrollExtent > notification.metrics.pixels && final pixels = notification.metrics.pixels;
notification.metrics.maxScrollExtent - notification.metrics.pixels <= final extentBefore = notification.metrics.extentBefore;
widget.scrollOffset) { final extentAfter = notification.metrics.extentAfter;
if (_loadMoreStatus != null && final scrollOffset = widget.scrollOffset;
_loadMoreStatus == _LoadingStatus.STABLE) {
_loadMoreStatus = _LoadingStatus.LOADING; final scrollingDown = _scrollPosition < pixels;
if (widget.onEndOfPage != null) {
widget.onEndOfPage().whenComplete(() { if (scrollOffset == null || scrollOffset == 0) {
_loadMoreStatus = _LoadingStatus.STABLE; if (extentAfter == 0) {
}); _onEndOfPage();
} }
if (extentBefore == 0) {
_onStartOfPage();
} }
} } else {
if (notification.metrics.minScrollExtent < notification.metrics.pixels && if (scrollingDown) {
notification.metrics.pixels - notification.metrics.minScrollExtent <= if (extentAfter <= scrollOffset) {
widget.scrollOffset) { _onEndOfPage();
if (_loadMoreStatus != null && }
_loadMoreStatus == _LoadingStatus.STABLE) { } else {
_loadMoreStatus = _LoadingStatus.LOADING; if (extentBefore <= scrollOffset) {
if (widget.onStartOfPage != null) { _onStartOfPage();
widget.onStartOfPage().whenComplete(() {
_loadMoreStatus = _LoadingStatus.STABLE;
});
} }
} }
} }
_scrollPosition = pixels;
return true; return true;
} }
if (notification is OverscrollNotification) { if (notification is OverscrollNotification) {
if (notification.overscroll > 0) { if (notification.overscroll > 0) {
if (_loadMoreStatus != null && _onEndOfPage();
_loadMoreStatus == _LoadingStatus.STABLE) {
_loadMoreStatus = _LoadingStatus.LOADING;
if (widget.onEndOfPage != null) {
widget.onEndOfPage().whenComplete(() {
_loadMoreStatus = _LoadingStatus.STABLE;
});
}
}
} }
if (notification.overscroll < 0) { if (notification.overscroll < 0) {
if (_loadMoreStatus != null && _onStartOfPage();
_loadMoreStatus == _LoadingStatus.STABLE) {
_loadMoreStatus = _LoadingStatus.LOADING;
if (widget.onStartOfPage != null) {
widget.onStartOfPage().whenComplete(() {
_loadMoreStatus = _LoadingStatus.STABLE;
});
}
}
} }
return true; return true;
} }
return false; return false;
} }
void _onEndOfPage() {
if (_loadMoreStatus != null && _loadMoreStatus == _LoadingStatus.STABLE) {
_loadMoreStatus = _LoadingStatus.LOADING;
if (widget.onEndOfPage != null) {
widget.onEndOfPage().whenComplete(() {
_loadMoreStatus = _LoadingStatus.STABLE;
});
}
}
}
void _onStartOfPage() {
if (_loadMoreStatus != null && _loadMoreStatus == _LoadingStatus.STABLE) {
_loadMoreStatus = _LoadingStatus.LOADING;
if (widget.onStartOfPage != null) {
widget.onStartOfPage().whenComplete(() {
_loadMoreStatus = _LoadingStatus.STABLE;
});
}
}
}
} }
+6 -5
View File
@@ -294,13 +294,13 @@ class _MessageListViewState extends State<MessageListView> {
if (!_upToDate) { if (!_upToDate) {
_topPaginationActive = false; _topPaginationActive = false;
_bottomPaginationActive = true; _bottomPaginationActive = true;
_paginateData(streamChannel, QueryDirection.bottom); return _paginateData(streamChannel, QueryDirection.bottom);
} }
}, },
onEndOfPage: () async { onEndOfPage: () async {
_topPaginationActive = true; _topPaginationActive = true;
_bottomPaginationActive = false; _bottomPaginationActive = false;
_paginateData(streamChannel, QueryDirection.top); return _paginateData(streamChannel, QueryDirection.top);
}, },
child: ScrollablePositionedList.builder( child: ScrollablePositionedList.builder(
key: ValueKey(initialIndex + initialAlignment), key: ValueKey(initialIndex + initialAlignment),
@@ -453,11 +453,12 @@ class _MessageListViewState extends State<MessageListView> {
}); });
} }
void _paginateData(StreamChannelState channel, QueryDirection direction) { Future<void> _paginateData(
StreamChannelState channel, QueryDirection direction) {
if (widget.parentMessage == null) { if (widget.parentMessage == null) {
channel.queryMessages(direction: direction); return channel.queryMessages(direction: direction);
} else { } else {
channel.getReplies(widget.parentMessage.id); return channel.getReplies(widget.parentMessage.id);
} }
} }