[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
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;
/// 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> {
_LoadingStatus _loadMoreStatus = _LoadingStatus.STABLE;
double _scrollPosition = 0.0;
@override
Widget build(BuildContext context) {
@@ -49,59 +50,65 @@ class _LazyLoadScrollViewState extends State<LazyLoadScrollView> {
bool _onNotification(Notification notification) {
if (notification is ScrollUpdateNotification) {
if (notification.metrics.maxScrollExtent > notification.metrics.pixels &&
notification.metrics.maxScrollExtent - notification.metrics.pixels <=
widget.scrollOffset) {
if (_loadMoreStatus != null &&
_loadMoreStatus == _LoadingStatus.STABLE) {
_loadMoreStatus = _LoadingStatus.LOADING;
if (widget.onEndOfPage != null) {
widget.onEndOfPage().whenComplete(() {
_loadMoreStatus = _LoadingStatus.STABLE;
});
}
final pixels = notification.metrics.pixels;
final extentBefore = notification.metrics.extentBefore;
final extentAfter = notification.metrics.extentAfter;
final scrollOffset = widget.scrollOffset;
final scrollingDown = _scrollPosition < pixels;
if (scrollOffset == null || scrollOffset == 0) {
if (extentAfter == 0) {
_onEndOfPage();
}
if (extentBefore == 0) {
_onStartOfPage();
}
}
if (notification.metrics.minScrollExtent < notification.metrics.pixels &&
notification.metrics.pixels - notification.metrics.minScrollExtent <=
widget.scrollOffset) {
if (_loadMoreStatus != null &&
_loadMoreStatus == _LoadingStatus.STABLE) {
_loadMoreStatus = _LoadingStatus.LOADING;
if (widget.onStartOfPage != null) {
widget.onStartOfPage().whenComplete(() {
_loadMoreStatus = _LoadingStatus.STABLE;
});
} else {
if (scrollingDown) {
if (extentAfter <= scrollOffset) {
_onEndOfPage();
}
} else {
if (extentBefore <= scrollOffset) {
_onStartOfPage();
}
}
}
_scrollPosition = pixels;
return true;
}
if (notification is OverscrollNotification) {
if (notification.overscroll > 0) {
if (_loadMoreStatus != null &&
_loadMoreStatus == _LoadingStatus.STABLE) {
_loadMoreStatus = _LoadingStatus.LOADING;
if (widget.onEndOfPage != null) {
widget.onEndOfPage().whenComplete(() {
_loadMoreStatus = _LoadingStatus.STABLE;
});
}
}
_onEndOfPage();
}
if (notification.overscroll < 0) {
if (_loadMoreStatus != null &&
_loadMoreStatus == _LoadingStatus.STABLE) {
_loadMoreStatus = _LoadingStatus.LOADING;
if (widget.onStartOfPage != null) {
widget.onStartOfPage().whenComplete(() {
_loadMoreStatus = _LoadingStatus.STABLE;
});
}
}
_onStartOfPage();
}
return true;
}
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) {
_topPaginationActive = false;
_bottomPaginationActive = true;
_paginateData(streamChannel, QueryDirection.bottom);
return _paginateData(streamChannel, QueryDirection.bottom);
}
},
onEndOfPage: () async {
_topPaginationActive = true;
_bottomPaginationActive = false;
_paginateData(streamChannel, QueryDirection.top);
return _paginateData(streamChannel, QueryDirection.top);
},
child: ScrollablePositionedList.builder(
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) {
channel.queryMessages(direction: direction);
return channel.queryMessages(direction: direction);
} else {
channel.getReplies(widget.parentMessage.id);
return channel.getReplies(widget.parentMessage.id);
}
}