我正在尝试在我的Flutter应用中实现分页,但这是我第一次这么做。我的想法是创建一个Stream
的数据,每当用户到达列表底部时,它就会更新。我没有成功地实现这一点。我目前的代码具有获取新数据并将其添加到现有数据的逻辑。但是现在它甚至没有返回第一个数据范围,所以快照是空的。至于分页功能,我尝试使用ChangeNotifier
通知Stream
更新,但我不知道这是否有效。请看一下下面的代码,然后告诉我应该修改什么。DataProvider
类:
class DataProvider extends ChangeNotifier{
DataProvider() : super();
static var changeController = ChangeNotifier();
static void reload() {
changeController.notifyListeners();
}
static int lastRange = 0;
static List data = [];
static Stream<List> paginatedUsersAndPosts() async* {
List<UserSearchResult> usersList = data.first;
List<Post> postsList = data.last;
print('Notifier');
changeController.addListener(() async {
print('Change notified, getting data');
List<int> range() {
if (lastRange == 0) {
lastRange = 10;
return [0, 10];
} else {
// Example 0, 10 => 11, 20
int newMin = lastRange + 1;
int newMax = lastRange + 10;
lastRange = newMax;
return [newMin, newMax];
}
}
List<Map<String, dynamic>> postsDocs = await Supabase.db
.from('posts')
.select()
.order('date', ascending: false)
.range(range().first, range().last);
List<Post> newPostsList =
postsDocs.map((postDoc) => Post.fromJson(postDoc)).toList();
newPostsList.forEach((post) async {
postsList.add(post);
if (usersList.where((u) => u.uid == post.uid).isNotEmpty) {
Map<String, dynamic> userDoc =
await Supabase.db.from('profiles').select().single();
ProfileInfoObject profileInfo = ProfileInfoObject.fromJson(userDoc);
print('New profile: $profileInfo');
Profile profile = Profile(profileInfo, []);
profile.posts.add(post);
List blockedUsers = userDoc['blockedUsers'] as List;
UserSearchResult user = (UserSearchResult(
profile, userDoc['uid'].toString(), blockedUsers));
usersList.add(user);
}
});
});
yield [usersList, postsList];
}
}
使用流的主要小部件:
class FloatingTabBarView extends StatefulWidget {
const FloatingTabBarView({Key? key}) : super(key: key);
@override
State<FloatingTabBarView> createState() => _FloatingTabBarViewState();
}
class _FloatingTabBarViewState extends State<FloatingTabBarView> {
@override
void initState() {
PermissionsService.checkPermissions(context);
DataProvider.reload();
super.initState();
}
Stream<List> stream = DataProvider.paginatedUsersAndPosts();
return StreamBuilder<List>(
stream: stream,
builder: (context, AsyncSnapshot<List<dynamic>> snapshot) {
...
});
}
@override
Widget build(BuildContext context) {
return floatingTabBarPageView();
}
}
2条答案
按热度按时间fcwjkofz1#
请看一下pull_to_refresh包。这允许实现拉取以刷新和增量加载数据。使用
RefreshController
在数据刷新或加载时进行更新。1.示例化
RefreshController
1.用
SmartRefresher
包裹ListView
1.实现
onLoading
回调以增量方式获取数据1.完成或出错时更新
RefreshController
。这个软件包有一个很好的用法示例,请一定要去看看。
nkoocmlb2#
问题在于我创建流的方式,因为我把
Stream
作为函数,所以我无法调用该函数来重新加载,而是把代码移到一个可以从任何页面调用的static void
中,创建一个StreamController
,并在void
的末尾使用controller.add(data)
,这样我就可以用新数据更新流。