[LazyLoadScrollView] Fix callback logic
Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
@@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user