如何在Flutter中使用infinite_scroll_pagination实现无限分页?
用infinite_scroll_pagination实现无限滚动分页(结合Dio)
步骤1:添加依赖
在pubspec.yaml的dependencies区块中加入:
infinite_scroll_pagination: ^4.0.0 # 使用最新稳定版本 dio: ^5.0.0
执行flutter pub get完成依赖安装。
步骤2:重构状态变量与分页控制器
替换原有分页相关变量,改用infinite_scroll_pagination提供的分页控制器:
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; // 分页控制器:泛型参数为页码类型、列表项数据类型 final PagingController<int, Event> _pagingController = PagingController(firstPageKey: 1); String? _nextPageUrl; // 存储API返回的下一页请求地址 Dio dio = Dio();
步骤3:实现分页数据获取逻辑
重写数据请求方法,适配API返回的分页信息:
Future<void> _fetchPage(int pageKey) async { try { // 首次请求用初始地址,后续用API返回的下一页地址 final requestUrl = _nextPageUrl ?? 'http://52.90.175.175/api/events/get?page=$pageKey'; final response = await dio.get(requestUrl); final dataList = response.data["data"]["data"] as List; final newEvents = dataList.map((i) => Event.fromJson(i)).toList(); // 从API返回中提取下一页地址(根据实际JSON结构调整字段名) _nextPageUrl = response.data["data"]["next_page_url"]; final isLastPage = _nextPageUrl == null; if (isLastPage) { _pagingController.appendLastPage(newEvents); } else { final nextPageKey = pageKey + 1; _pagingController.appendPage(newEvents, nextPageKey); } } catch (e) { _pagingController.error = e; } }
步骤4:初始化与销毁控制器
在页面生命周期中处理控制器的监听与释放:
@override void initState() { super.initState(); // 监听分页请求事件,触发数据加载 _pagingController.addPageRequestListener((pageKey) { _fetchPage(pageKey); }); } @override void dispose() { _pagingController.dispose(); super.dispose(); }
步骤5:替换ListView为PagedListView
用PagedListView.builder替代原有列表组件,实现无限滚动:
PagedListView<int, Event>( pagingController: _pagingController, builderDelegate: PagedChildBuilderDelegate<Event>( itemBuilder: (context, item, index) { return ListTile( contentPadding: const EdgeInsets.all(20), title: Text(item.title), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(item.description), Text("${item.start} - ${item.end}"), ], ), ); }, // 可选:自定义状态UI firstPageErrorIndicatorBuilder: (context) => const Center(child: Text('加载失败,请重试')), newPageErrorIndicatorBuilder: (context) => const Center(child: Text('加载更多失败,请重试')), firstPageProgressIndicatorBuilder: (context) => const Center(child: CircularProgressIndicator()), newPageProgressIndicatorBuilder: (context) => const Center(child: CircularProgressIndicator()), ), )
关键注意点
- 分页字段适配:需根据API实际返回的JSON结构调整
_nextPageUrl的提取逻辑,比如部分API可能用next_page而非next_page_url。 - 错误处理:
PagedChildBuilderDelegate提供了多种状态的自定义UI,可根据产品需求修改。 - 页码逻辑:如果API的下一页地址已包含完整请求参数,也可以不依赖
pageKey,直接通过_nextPageUrl是否为空判断是否还有更多数据。
内容的提问来源于stack exchange,提问作者Afthal Ad
相关产品推荐
相关产品推荐

