You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 00:21:01