如何保存infinite_scroll_pagination中PagedListView的状态与已加载数据?
解决PagedListView在PageView切换时的状态与数据丢失问题
核心原因
PageView默认会销毁非当前显示的子页面,导致PagedListView内部的PagedViewController被回收,已加载的分页数据和状态随之丢失。PageStorage仅负责保存滚动位置,无法维护控制器的分页状态与数据,因此单独使用无效。
解决方案一:将PagedViewController提升至父组件
把PagedViewController的实例放在PageView所在的父组件中,让控制器生命周期与父组件绑定,避免子页面销毁时丢失数据。
// 父组件:持有PagedViewController并传递给子页面 class ParentPage extends StatefulWidget { @override _ParentPageState createState() => _ParentPageState(); } class _ParentPageState extends State<ParentPage> { late final PagedViewController<int, Item> _pagedViewController; @override void initState() { super.initState(); _pagedViewController = PagedViewController( firstPageKey: 0, pageRequest: (pageKey) async { // 替换为你的实际数据请求逻辑 final items = await fetchItems(pageKey); return PagedResponse( data: items, nextPageKey: items.isNotEmpty ? pageKey + 1 : null, ); }, ); } @override void dispose() { _pagedViewController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return PageView( children: [ PagedListSubPage(controller: _pagedViewController), // 其他子页面 ], ); } } // 子页面:使用父组件传入的控制器 class PagedListSubPage extends StatelessWidget { final PagedViewController<int, Item> controller; const PagedListSubPage({super.key, required this.controller}); @override Widget build(BuildContext context) { return PagedListView( pagedViewController: controller, builderDelegate: PagedChildBuilderDelegate<Item>( itemBuilder: (context, item, index) => ListTile(title: Text(item.name)), ), ); } }
解决方案二:使用AutomaticKeepAliveClientMixin保持子页面存活
通过该Mixin阻止PageView销毁非当前子页面,让页面的状态和控制器得以保留。
class PagedListSubPage extends StatefulWidget { @override _PagedListSubPageState createState() => _PagedListSubPageState(); } class _PagedListSubPageState extends State<PagedListSubPage> with AutomaticKeepAliveClientMixin { late final PagedViewController<int, Item> _pagedViewController; @override void initState() { super.initState(); _pagedViewController = PagedViewController( firstPageKey: 0, pageRequest: (pageKey) async { final items = await fetchItems(pageKey); return PagedResponse( data: items, nextPageKey: items.isNotEmpty ? pageKey + 1 : null, ); }, ); } @override void dispose() { _pagedViewController.dispose(); super.dispose(); } // 关键:返回true表示需要保持页面存活 @override bool get wantKeepAlive => true; @override Widget build(BuildContext context) { // 必须调用super.build(context),否则Mixin不生效 super.build(context); return PagedListView( pagedViewController: _pagedViewController, builderDelegate: PagedChildBuilderDelegate<Item>( itemBuilder: (context, item, index) => ListTile(title: Text(item.name)), ), ); } }
进阶优化
如果需要同时保留滚动位置,可以在PagedListView中添加pageStorageKey,结合上述方案使用:
PagedListView( pageStorageKey: const PageStorageKey('paged_list_key'), pagedViewController: controller, // ...其他配置 )
内容的提问来源于stack exchange,提问作者Kyrillus K
相关产品推荐
相关产品推荐

