Flutter中NestedScrollView内绑定控制器的ListView滚动时AppBar不隐藏
问题解决:NestedScrollView绑定自定义scrollController后SliverAppBar无法隐藏
问题根因
NestedScrollView内部默认会维护一个全局共享的PrimaryScrollController,用来同步SliverAppBar和内部body滚动组件的滚动事件,实现AppBar随滚动隐藏/展示的联动效果。
当你手动给body内的ListView指定自定义的scrollController后,该ListView的滚动事件只会传递给你自定义的控制器,不会同步到NestedScrollView的共享控制器,SliverAppBar收不到滚动信号,自然不会触发隐藏逻辑。未指定控制器时ListView默认自动复用上层的PrimaryScrollController,所以联动功能正常。
解决方案
直接复用NestedScrollView提供的共享滚动控制器即可,无需单独创建自定义scrollController,你需要的滚动监听、加载更多等逻辑都可以直接绑定在这个共享控制器上,实现步骤如下:
- 删掉你原来自行创建
ScrollController的代码 - 在组件的
didChangeDependencies生命周期中获取共享控制器,绑定你的业务逻辑:
late ScrollController scrollController; @override void didChangeDependencies() { super.didChangeDependencies(); // 获取NestedScrollView内置的共享滚动控制器 scrollController = PrimaryScrollController.of(context)!; // 绑定你原来的滚动监听逻辑,比如加载更多 scrollController.addListener(() { if (scrollController.position.pixels >= scrollController.position.maxScrollExtent - 200) { // 你的加载更多逻辑 loadMorePosts(); } }); }
- 原有ListView的
controller参数保留,继续传入这个scrollController即可,其他代码无需修改。
备选方案(仅当你必须使用独立自定义控制器时)
如果业务场景要求你必须使用完全独立的自定义scrollController,可以给ListView添加如下配置,让滚动事件向上冒泡通知到NestedScrollView:
ListView.separated( controller: scrollController, // 新增以下两个配置 primary: false, physics: const AlwaysScrollableScrollPhysics(parent: BouncingScrollPhysics()), // 其余原有配置不变 padding: const EdgeInsets.symmetric(vertical:15), itemCount: posts.length, separatorBuilder: (context,index)=>const SizedBox(height: 6,), itemBuilder: (context,index)=>posts[index], )
该方案性能略低于第一种方案,非必要场景优先选择复用共享控制器的方案。
内容的提问来源于stack exchange,提问作者Deepak Lohmod
相关产品推荐
相关产品推荐

