Flutter:实现带固定拖动触发区的可拖动底部表单问题
解决DraggableScrollableSheet固定头部的滚动问题
需求与当前问题
- 需求:底部表单初始仅显示顶部白色触发条,向上拖动展开至最大高度(屏幕高度的80%)后,触发条和标题栏固定,仅下方列表可滚动
- 当前问题:表单拉到最大高度时,滚动标题区域会带动整个sheet滚动,不符合预期
问题原因
原代码将整个内容包裹在SingleChildScrollView中,并把同一个scrollController同时绑定给外层滚动组件和内部ListView,导致头部区域的滚动事件被外层组件捕获,进而带动整个sheet移动。
修改后的代码
DraggableScrollableSheet( initialChildSize: 0.05, minChildSize: 0.05, maxChildSize: 0.8, builder: (BuildContext context, ScrollController scrollController) { return Container( margin: const EdgeInsets.only(top: 10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), color: Colors.blueGrey, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.5), spreadRadius: 2, blurRadius: 7, offset: const Offset(0, 3), ), ], ), padding: const EdgeInsets.symmetric(horizontal: 15), child: Column( children: <Widget>[ // 顶部触发条 SizedBox( height: 20, child: Center( child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), color: Colors.white, ), width: 70, height: 7, ), ), ), // 标题栏 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ const Text('My cars'), IconButton( color: Colors.black, focusColor: Colors.red, splashRadius: 20, onPressed: () {}, icon: const Icon( CupertinoIcons.add, size: 15, ), ) ], ), // 可滚动列表 Expanded( child: ListView.builder( controller: scrollController, itemCount: 25, itemBuilder: (BuildContext context, int index) { return ListTile(title: Text('Item $index')); }, ), ), ], ), ); }, )
关键修改点
- 移除外层
SingleChildScrollView,消除滚动事件冲突 - 将触发条和标题栏设为
Column的固定子项,始终保持在顶部 - 仅将
DraggableScrollableSheet提供的scrollController绑定到内部ListView,确保sheet到达最大高度后,只有列表区域响应滚动操作 - 用
margin替代原顶部padding,避免多余间距影响布局
内容的提问来源于stack exchange,提问作者Michel Gisenaël
相关产品推荐
相关产品推荐

