如何在SingleChildScrollView中实现不可滚动的ListView.builder
解决SingleChildScrollView嵌套ListView.builder的滚动冲突问题
我来帮你搞定这个问题~你现在的需求是让整个页面(包括ListView里的内容)都由外层的SingleChildScrollView统一控制滚动,不想让ListView自己滚动,对吧?
问题出在默认的ListView.builder有两个特性:它会试图占据所有可用的垂直空间,并且自带滚动行为,这就导致和外层的SingleChildScrollView产生了滚动冲突。只要给ListView.builder加上两个属性就能完美解决:
shrinkWrap: true:让ListView根据所有子项的总高度来收缩自身尺寸,不再强行占满垂直空间physics: const NeverScrollableScrollPhysics():直接禁用ListView自身的滚动能力,把所有滚动操作都交给父级的SingleChildScrollView
修改后的完整代码如下:
class _DashboardState extends State<Dashboard> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('App Bar Here')), body: SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('Hello World'), Container( child: ListView.builder( // 添加这两个关键属性 shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { return Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: <Widget>[ Container( color: Color(0xffaaaaaa), height: 20, child: Text('Jss One')), Text( 'English', style: TextStyle(fontSize: 20), ), ], ), ), ); }, itemCount: 50, ), ), ], ), ), ); } }
这样修改后,整个页面的所有内容(包括顶部的Text和ListView里的50个Card)都会统一跟着SingleChildScrollView滚动,完全不会出现嵌套滚动的冲突问题了。
另外提个小提示:如果你的ListView子项数量特别多(比如上千个),shrinkWrap可能会带来一些性能开销,因为它需要先计算所有子项的高度。但你这里只有50个,完全不用担心这个问题,放心用就好~
内容的提问来源于stack exchange,提问作者AbdLim
相关产品推荐
相关产品推荐

