Flutter的showModalBottomSheet无法拖拽及设置多档停靠锚点如何实现
问题修复方案
无法拖拽的根因
- 开启
isScrollControlled: true后,原生showModalBottomSheet的默认拖拽事件会被内部组件优先拦截,你额外添加的固定高度Container+GestureDetector进一步冲突了手势分发逻辑 - 原生
showModalBottomSheet本身不支持多锚点停靠配置,仅支持默认高度/全屏两种状态,自定义档位需要搭配DraggableScrollableSheet实现
完整实现代码
替换你现有的showModalBottomSheet逻辑即可:
showModalBottomSheet( context: context, isScrollControlled: true, isDismissible: true, enableDrag: true, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), clipBehavior: Clip.antiAliasWithSaveLayer, builder: (context) { return DraggableScrollableSheet( // 开启档位停靠能力 snap: true, // 配置你需要的四个拖拽锚点 snapSizes: const [0.3, 0.6, 0.9, 1.0], // 弹窗初始显示高度,对应0.9档位 initialChildSize: 0.9, // 最小/最大高度和锚点首尾对齐 minChildSize: 0.3, maxChildSize: 1.0, expand: false, builder: (context, scrollController) { // 若PlayerCardDialog内部有可滚动组件,把scrollController传给对应组件的controller参数 return PlayerCardDialog( epdId: episodes[index['Ep_ID']], // 内部有ListView/GridView时打开下面的注释 // controller: scrollController, ); }, ); }, );
注意事项
- 无需保留原有自定义高度的
StreamBuilder和GestureDetector逻辑,DraggableScrollableSheet会自动处理手势分发和高度切换 - 如果弹窗内部有可滚动组件,必须把
builder提供的scrollController传给内部滚动组件,否则会出现滚动和拖拽手势冲突 - 需要监听当前所处档位时,可在外层套
NotificationListener<ScrollUpdateNotification>,通过notification.metrics.extent获取当前高度占比,匹配对应锚点即可
内容的提问来源于stack exchange,提问作者user16886755
相关产品推荐
相关产品推荐

