嵌套在PageView及SingleChildScrollView中的ListView.builder出现无限高度错误
问题:实现全屏滚动而非仅ListView滚动
Flutter环境信息
Doctor summary (to see all details, run flutter doctor -v): [√] Flutter (Channel stable, 3.3.9, on Microsoft Windows [Version 10.0.19044.2251], locale en-US) [√] Android toolchain - develop for Android devices (Android SDK version 33.0.1) [√] Chrome - develop for the web [X] Visual Studio - develop for Windows X Visual Studio not installed; this is necessary for Windows development. 请前往微软官网下载Visual Studio,并安装包含所有默认组件的“使用C++的桌面开发”工作负载 [√] Android Studio (version 2021.3) [√] VS Code (version 1.74.0) [√] Connected device (4 available) [√] HTTP Host Availability ! Doctor found issues in 1 category.
最小复现代码
import 'package:flutter/material.dart'; class Temp extends StatefulWidget { const Temp({Key? key}) : super(key: key); @override State<Temp> createState() => _TempState(); } class _TempState extends State<Temp> { @override Widget build(BuildContext context) { PageController pageController = PageController( initialPage: 0, ); return Scaffold( body: Container( padding: const EdgeInsets.symmetric(horizontal: 30), margin: EdgeInsets.only(top: MediaQuery.of(context).viewPadding.top + 10), child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( color: Colors.orangeAccent, height: MediaQuery.of(context).size.height * 0.3, width: MediaQuery.of(context).size.width, child: const Center(child: Text('DUMMY BOX 3'))), Container( color: Colors.purpleAccent, height: MediaQuery.of(context).size.height * 0.2, width: MediaQuery.of(context).size.width, child: const Center(child: Text('DUMMY BOX 2'))), Container( color: Colors.lightBlueAccent, height: MediaQuery.of(context).size.height * 0.3, width: MediaQuery.of(context).size.width, child: const Center( child: Text('DUMMY BOX 3'), ), ), const SizedBox( height: 40, ), PageView( controller: pageController, children: const [ DummyListViewContainerWidget(), DummyListViewContainerWidget(), DummyListViewContainerWidget() ], ), ], ), ), ), ); } } class DummyListViewContainerWidget extends StatelessWidget { const DummyListViewContainerWidget({ Key? key, }) : super(key: key); @override Widget build(BuildContext context) { return ListView.separated( // physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemCount: 10, padding: const EdgeInsets.only(bottom: 20), separatorBuilder: (cxt, index) { return const SizedBox( height: 10, ); }, itemBuilder: (cxt, index) { return Container( height: 50, width: MediaQuery.of(context).size.width, color: Colors.brown, child: Center(child: Text(index.toString())), ); }); } }
期望效果
整个屏幕可滚动,而非仅ListView可滚动。
已尝试方案
- 给SingleChildScrollView下方的Column设置MainAxisSize.min
- 给PageView设置固定高度,但此方案会截断ListView内容,不符合需求
- 移除顶部的SingleChildScrollView,将其放入PageView内部
解决方案
要实现全屏滚动,需让外部SingleChildScrollView接管整个页面滚动,同时禁止内部ListView的滚动,并让PageView自适应子内容高度,具体修改如下:
禁止内部ListView滚动:在
DummyListViewContainerWidget的ListView.separated中添加physics: const NeverScrollableScrollPhysics(),让内部ListView不再拦截滚动事件,将滚动操作交给外部的SingleChildScrollView。让PageView自适应高度:用
IntrinsicHeight包裹PageView,该组件会让PageView的高度适配其最高子项的高度,确保PageView能完全展示内部ListView的所有内容,同时让外部SingleChildScrollView可以滚动整个页面。
修改后的DummyListViewContainerWidget
class DummyListViewContainerWidget extends StatelessWidget { const DummyListViewContainerWidget({ Key? key, }) : super(key: key); @override Widget build(BuildContext context) { return ListView.separated( physics: const NeverScrollableScrollPhysics(), // 禁止内部滚动 shrinkWrap: true, itemCount: 10, padding: const EdgeInsets.only(bottom: 20), separatorBuilder: (cxt, index) { return const SizedBox( height: 10, ); }, itemBuilder: (cxt, index) { return Container( height: 50, width: MediaQuery.of(context).size.width, color: Colors.brown, child: Center(child: Text(index.toString())), ); }); } }
修改后的PageView部分
IntrinsicHeight( child: PageView( controller: pageController, children: const [ DummyListViewContainerWidget(), DummyListViewContainerWidget(), DummyListViewContainerWidget() ], ), ),
修改完成后,整个页面(包括上方三个盒子和下方PageView内的所有列表项)均可通过外部的SingleChildScrollView滚动,同时PageView仍支持横向切换页面。
内容的提问来源于stack exchange,提问作者Anas Yousuf
相关产品推荐
相关产品推荐

