Flutter中ListView.builder无法滚动问题求助
解决CustomScrollView中嵌套ListView.builder无法滚动的问题
你的问题核心是滚动容器嵌套导致的事件冲突:外层CustomScrollView已经接管了整个页面的滚动逻辑,内层ListView.builder的滚动事件被拦截,无法正常触发。以下是两种可行的解决方案,优先推荐第一种符合Flutter设计规范的实现方式。
方案一:用SliverList替代ListView.builder(最优解)
CustomScrollView的设计初衷就是组合各类Sliver组件(如SliverAppBar、SliverList等),所有组件共享同一滚动上下文,不会出现滚动冲突。直接将列表部分改为SliverList,和其他Sliver组件配合使用即可:
修改后的完整build代码:
class _DashboardScreenState extends State<DashboardScreen> { @override Widget build(BuildContext context) { final screenHeight = MediaQuery.of(context).size.height; return Scaffold( appBar: CustomAppBar(), body: CustomScrollView( physics: ClampingScrollPhysics(), slivers: <Widget>[ _buildHeader(screenHeight), // 按钮区域 SliverToBoxAdapter( child: Container( width: 100, height: 65, child: Padding( padding: const EdgeInsets.only(top: 20), child: ElevatedButton( onPressed: () {}, child: Text( 'Add', style: TextStyle(fontSize: 18), ), style: ElevatedButton.styleFrom( shape: StadiumBorder(), backgroundColor: Palette.primaryColor), ), ), ), ), SliverToBoxAdapter(child: SizedBox(height: 10)), // 列表区域改用SliverList SliverList( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { return Container( margin: const EdgeInsets.symmetric( vertical: 10.0, horizontal: 20.0, ), padding: const EdgeInsets.all(10.0), height: screenHeight * 0.15, decoration: BoxDecoration( gradient: LinearGradient( colors: [Color(0xFFAD9FE4), Palette.primaryColor], ), borderRadius: BorderRadius.circular(20.0), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ Image.asset( "assets/worker.png", height: 80, width: 80, ), Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text( 'Somme: 50 €', style: const TextStyle( color: Colors.white, fontSize: 18.0, fontWeight: FontWeight.bold, ), ), SizedBox(height: screenHeight * 0.01), Text( 'Date: 19 novembre 2022', style: TextStyle(fontSize: 10, color: Colors.white), ), SizedBox(height: screenHeight * 0.01), Text( 'Follow the instructions\nto do your own test.', style: const TextStyle( color: Colors.white, fontSize: 16.0, ), maxLines: 2, ), ], ) ], ), ); }, childCount: 6, ), ), ], ), ); } }
方案二:禁用ListView自身滚动(兼容旧写法,不推荐)
如果一定要保留ListView.builder的结构,可以禁用它的滚动物理,让滚动事件透传到外层CustomScrollView,同时保留shrinkWrap: true让ListView自适应内容高度:
修改后的ListView.builder代码片段:
ListView.builder( scrollDirection: Axis.vertical, physics: const NeverScrollableScrollPhysics(), // 禁用自身滚动逻辑 shrinkWrap: true, itemCount: 6, itemBuilder: ((BuildContext context, int index) { // 子项代码不变 }) )
注意:这种方式性能不如SliverList,因为
shrinkWrap: true需要遍历所有子项计算高度,而SliverList是按需加载的,适合大量数据场景。
内容的提问来源于stack exchange,提问作者Fedy Belaid
相关产品推荐
相关产品推荐

