[UserListView] Use LazyLoadScrollView for pagination rather than listening scroll controller
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
enum LoadingStatus { LOADING, STABLE }
|
||||
|
||||
/// Signature for EndOfPageListeners
|
||||
typedef EndOfPageListenerCallback = void Function();
|
||||
|
||||
/// A widget that wraps a [Widget] and will trigger [onEndOfPage] when it
|
||||
/// reaches the bottom of the list
|
||||
class LazyLoadScrollView extends StatefulWidget {
|
||||
/// The [Widget] that this widget watches for changes on
|
||||
final Widget child;
|
||||
|
||||
/// Called when the [child] reaches the end of the list
|
||||
final EndOfPageListenerCallback onEndOfPage;
|
||||
|
||||
/// The offset to take into account when triggering [onEndOfPage] in pixels
|
||||
final int 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
|
||||
final bool isLoading;
|
||||
|
||||
LazyLoadScrollView({
|
||||
Key key,
|
||||
@required this.child,
|
||||
@required this.onEndOfPage,
|
||||
this.isLoading = false,
|
||||
this.scrollOffset = 100,
|
||||
}) : assert(onEndOfPage != null),
|
||||
assert(child != null),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _LazyLoadScrollViewState();
|
||||
}
|
||||
|
||||
class _LazyLoadScrollViewState extends State<LazyLoadScrollView> {
|
||||
LoadingStatus _loadMoreStatus = LoadingStatus.STABLE;
|
||||
|
||||
@override
|
||||
void didUpdateWidget(LazyLoadScrollView oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (!widget.isLoading) {
|
||||
_loadMoreStatus = LoadingStatus.STABLE;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return NotificationListener(
|
||||
child: widget.child,
|
||||
onNotification: _onNotification,
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
widget.onEndOfPage();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (notification is OverscrollNotification) {
|
||||
if (notification.overscroll > 0) {
|
||||
if (_loadMoreStatus != null &&
|
||||
_loadMoreStatus == LoadingStatus.STABLE) {
|
||||
_loadMoreStatus = LoadingStatus.LOADING;
|
||||
widget.onEndOfPage();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+38
-48
@@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:stream_chat_flutter/src/lazy_load_scroll_view.dart';
|
||||
import 'package:stream_chat_flutter/src/users_bloc.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
@@ -144,8 +145,6 @@ class UserListView extends StatefulWidget {
|
||||
|
||||
class _UserListViewState extends State<UserListView>
|
||||
with WidgetsBindingObserver {
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
bool get _isListView => widget.crossAxisCount == 1;
|
||||
|
||||
@override
|
||||
@@ -158,14 +157,6 @@ class _UserListViewState extends State<UserListView>
|
||||
pagination: widget.pagination,
|
||||
options: widget.options,
|
||||
);
|
||||
|
||||
_scrollController.addListener(() {
|
||||
usersBloc.queryUsersLoading.first.then((loading) {
|
||||
if (!loading) {
|
||||
_listenUserPagination(usersBloc);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -327,32 +318,35 @@ class _UserListViewState extends State<UserListView>
|
||||
);
|
||||
}
|
||||
|
||||
if (_isListView) {
|
||||
return ListView.separated(
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
controller: _scrollController,
|
||||
itemCount: items.isNotEmpty ? items.length + 1 : items.length,
|
||||
separatorBuilder: (_, index) {
|
||||
if (widget.separatorBuilder != null) {
|
||||
return widget.separatorBuilder(context, index);
|
||||
}
|
||||
return _separatorBuilder(context, index);
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
return _listItemBuilder(context, index, items);
|
||||
},
|
||||
);
|
||||
}
|
||||
return GridView.builder(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: widget.crossAxisCount,
|
||||
),
|
||||
itemCount: items.isNotEmpty ? items.length + 1 : items.length,
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
controller: _scrollController,
|
||||
itemBuilder: (context, index) {
|
||||
return _gridItemBuilder(context, index, items);
|
||||
},
|
||||
final child = _isListView
|
||||
? ListView.separated(
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
// controller: _scrollController,
|
||||
itemCount: items.isNotEmpty ? items.length + 1 : items.length,
|
||||
separatorBuilder: (_, index) {
|
||||
if (widget.separatorBuilder != null) {
|
||||
return widget.separatorBuilder(context, index);
|
||||
}
|
||||
return _separatorBuilder(context, index);
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
return _listItemBuilder(context, index, items);
|
||||
},
|
||||
)
|
||||
: GridView.builder(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: widget.crossAxisCount,
|
||||
),
|
||||
itemCount: items.isNotEmpty ? items.length + 1 : items.length,
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return _gridItemBuilder(context, index, items);
|
||||
},
|
||||
);
|
||||
|
||||
return LazyLoadScrollView(
|
||||
onEndOfPage: () => _listenUserPagination(usersBlocState),
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -488,18 +482,14 @@ class _UserListViewState extends State<UserListView>
|
||||
}
|
||||
|
||||
void _listenUserPagination(UsersBlocState usersProvider) {
|
||||
if (_scrollController.position.maxScrollExtent ==
|
||||
_scrollController.offset &&
|
||||
_scrollController.offset != 0) {
|
||||
usersProvider.queryUsers(
|
||||
filter: widget.filter,
|
||||
sort: widget.sort,
|
||||
pagination: widget.pagination.copyWith(
|
||||
offset: usersProvider.users?.length ?? 0,
|
||||
),
|
||||
options: widget.options,
|
||||
);
|
||||
}
|
||||
usersProvider.queryUsers(
|
||||
filter: widget.filter,
|
||||
sort: widget.sort,
|
||||
pagination: widget.pagination.copyWith(
|
||||
offset: usersProvider.users?.length ?? 0,
|
||||
),
|
||||
options: widget.options,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user