Flutter中如何实现getStream.io的activity feed活动动态流分页?
Flutter 配合 getStream.io 实现 FlatFeed 动态流分页方案
offset动态修改的核心逻辑是每次成功请求到新页数据后,累加当前页实际返回的数据量即可,无需手动固定计算偏移值。
实现步骤
- 先在页面状态中定义核心分页变量:固定每页加载数量
limit(建议设置为10~20)、当前偏移量offset初始值为0、加载状态标记isLoading用来防止重复请求、可选的hasMore标记判断是否还有下一页数据。 - 封装动态流请求方法:请求前先判断是否处于加载中、是否还有更多数据,不符合条件直接终止请求;符合条件则先将
isLoading设为true,传入当前的offset和limit参数发起接口请求。 - 请求成功后的处理逻辑:如果返回的活动列表长度小于你设置的
limit,说明已经到了列表最后一页,将hasMore设为false;将新返回的活动数据追加到你的总列表中,同时把offset累加当前返回的列表长度;最后将isLoading改回false即可。 - 触发加载的时机:页面初始化时第一次调用请求方法拉取第一页数据;列表滚动到底部时自动触发下一次请求,此时
offset已经是累加后的新值,自动拉取下一页数据。
示例代码
import 'package:stream_feed/stream_feed.dart'; import 'package:flutter/material.dart'; class FeedPage extends StatefulWidget { const FeedPage({super.key}); @override State<FeedPage> createState() => _FeedPageState(); } class _FeedPageState extends State<FeedPage> { static const _pageLimit = 10; int _currentOffset = 0; bool _isLoading = false; bool _hasMore = true; final List<EnrichedActivity> _activities = []; late FlatFeed _flatFeed; @override void initState() { super.initState(); // 替换为你自己的flatFeed初始化逻辑 _flatFeed = FeedProvider.of(context).client.flatFeed('user'); _loadFeed(); } Future<void> _loadFeed() async { if (_isLoading || !_hasMore) return; setState(() => _isLoading = true); try { final activities = await _flatFeed.getEnrichedActivities( offset: _currentOffset, limit: _pageLimit, ); if (activities.length < _pageLimit) { _hasMore = false; } setState(() { _activities.addAll(activities); _currentOffset += activities.length; }); } catch (e) { // 自行添加错误处理逻辑 } finally { setState(() => _isLoading = false); } } // 下拉刷新逻辑 Future<void> _refreshFeed() async { _currentOffset = 0; _hasMore = true; _activities.clear(); await _loadFeed(); } @override Widget build(BuildContext context) { return RefreshIndicator( onRefresh: _refreshFeed, child: ListView.builder( itemCount: _activities.length + (_hasMore ? 1 : 0), itemBuilder: (context, index) { // 滚动到接近底部时触发下一页加载 if (index == _activities.length - 2) { _loadFeed(); } if (index == _activities.length) { return const Center(child: CircularProgressIndicator()); } // 替换为你自己的动态项UI return ListTile(title: Text(_activities[index].extraData?['content'] ?? '')); }, ), ); } }
注意事项
- 不要固定累加
limit数值作为新的offset,必须用实际返回的列表长度做累加,避免服务端返回数据不足时出现数据重复或丢失的问题 - 必须添加加载状态拦截,避免快速滚动时重复发起多次相同请求
内容的提问来源于stack exchange,提问作者Maham Suhail
相关产品推荐
相关产品推荐

