Flutter Web中DraggableScrollableSheet日期选择器跳项问题求助
解决方案:Flutter Web中DraggableScrollableSheet嵌套CupertinoDatePicker滚动跳项问题
问题根源
出现滚动跳项的核心原因是DraggableScrollableSheet的拖拽/滚动手势与CupertinoDatePicker自身的滚轮滚动手势在Web平台上发生冲突,导致事件被干扰,无法正常响应连续的滚动选择。
解决方案
方案一:移除DraggableScrollableSheet(推荐,若无需拖拽调整弹窗大小)
如果你的场景不需要拖拽调整底部弹窗的尺寸,直接去掉DraggableScrollableSheet,用普通的showModalBottomSheet即可解决冲突:
void _showDatePickerBottomSheet(BuildContext context) { showModalBottomSheet( context: context, isScrollControlled: true, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(25.0), topRight: Radius.circular(25.0), ), ), builder: (context) { return Container( height: 200, padding: EdgeInsets.only( bottom: MediaQuery.of(context).viewInsets.bottom, ), child: CupertinoDatePicker( mode: CupertinoDatePickerMode.date, initialDateTime: DateTime.now(), onDateTimeChanged: (DateTime newDateTime) { _readingDate = DateFormat('dd/MM/yyyy').format(newDateTime).toString(); setState(() {}); // 调用setState更新界面显示 }, ), ); }, ); }
方案二:保留DraggableScrollableSheet,拦截手势冲突
如果必须保留拖拽调整尺寸的功能,需要给CupertinoDatePicker包裹手势拦截器,阻止其区域的滚动事件传递给DraggableScrollableSheet:
void _showDatePickerBottomSheet(BuildContext context) { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) { return GestureDetector( onTap: () { Navigator.of(context).pop(); setState(() {}); }, child: Container( padding: EdgeInsets.only( bottom: MediaQuery.of(context).viewInsets.bottom, ), color: const Color.fromRGBO(0, 0, 0, 0.001), child: GestureDetector( onTap: () {}, child: DraggableScrollableSheet( initialChildSize: 0.5, minChildSize: 0.2, maxChildSize: 1, builder: (_, controller) { return Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(25.0), topRight: Radius.circular(25.0), ), ), child: Column( children: [ // 顶部拖拽手柄,用于调整弹窗大小(可选,提升交互体验) const SizedBox( height: 40, child: Center( child: Container( width: 40, height: 6, decoration: BoxDecoration( color: Colors.grey, borderRadius: BorderRadius.all(Radius.circular(3)), ), ), ), ), // 拦截日期选择器区域的垂直拖拽事件 Expanded( child: GestureDetector( behavior: HitTestBehavior.opaque, onVerticalDragStart: (_) {}, // 拦截垂直拖拽,避免与DraggableSheet冲突 child: CupertinoDatePicker( mode: CupertinoDatePickerMode.date, initialDateTime: DateTime.now(), onDateTimeChanged: (DateTime newDateTime) { _readingDate = DateFormat('dd/MM/yyyy').format(newDateTime).toString(); setState(() {}); }, ), ), ), ], ), ); }, ), ), ), ); }, ); }
额外注意点
- 记得在
onDateTimeChanged回调中调用setState(),确保界面能实时更新选中的日期; - Web平台上Cupertino组件的手势兼容性不如移动端,若追求更稳定的体验,也可以考虑使用Flutter官方的
showDatePicker替代CupertinoDatePicker。
内容的提问来源于stack exchange,提问作者John Reaper
相关产品推荐
相关产品推荐

