Flutter NestedScrollView中TabBarView的两个ListView同步滚动问题求解
问题成因
- Flutter可滚动组件默认会优先绑定父级树中提供的
PrimaryScrollController,NestedScrollView默认会向其子树插入全局的PrimaryScrollController供内部子滚动组件使用 - 你通过
AutomaticKeepAliveClientMixin将两个Tab页的ListView都设为保活状态,两个ListView同时处于活跃挂载状态,且都未显式指定独立的ScrollController,默认都绑定了同一个PrimaryScrollController,因此同一个控制器的滚动事件会同步到两个ListView上,出现同步滚动的问题 - 额外冗余问题:代码中混用了
DefaultTabController和自定义的TabController,属于无效配置,也可能引发未知的状态冲突。
解决方案
按优先级处理即可修复问题:
- 为两个ListView分别配置独立的
ScrollController,同时显式设置primary: false,禁止其默认绑定全局PrimaryScrollController
示例代码如下:
// ListView1对应State类示例 class _ListView1State extends State<ListView1> with AutomaticKeepAliveClientMixin<ListView1>{ // 单独声明当前ListView专属的滚动控制器 final ScrollController _scrollController = ScrollController(); @override bool get wantKeepAlive => true; @override Widget build(BuildContext context) { // 使用保活Mixin必须调用super.build super.build(context); return ListView.builder( // 绑定专属控制器 controller: _scrollController, // 禁用默认全局滚动控制器绑定 primary: false, // 其余原有配置保持不变 itemCount: 100, itemBuilder: (context, index) => ListTile(title: Text('列表1项$index')), ); } // 页面销毁时释放控制器避免内存泄漏 @override void dispose() { _scrollController.dispose(); super.dispose(); } } // ListView2做完全相同的处理,单独声明自己的ScrollController即可
- 移除外层冗余的
DefaultTabController包裹,你已经显式创建了自定义tabController并传递给了TabBar和TabBarView,外层的DefaultTabController完全没有作用,删除即可避免逻辑冲突。
内容的提问来源于stack exchange,提问作者Fiaz Ali
相关产品推荐
相关产品推荐

