CupertinoSlidingSegmentedControl嵌套SingleChildScrollView在iOS无法滚动问题
解决CupertinoSlidingSegmentedControl在iOS无法水平滚动的问题
在iOS平台上,CupertinoSlidingSegmentedControl会拦截水平方向的触摸拖拽事件,用于处理自身的选项滑动切换逻辑,这导致外层的SingleChildScrollView无法接收到滚动触发事件;而Android平台的控件事件处理逻辑不同,因此可以正常滚动。
以下是两种可行的解决方案:
方案一:通过GestureDetector手动控制滚动
给CupertinoSlidingSegmentedControl包裹GestureDetector,监听水平拖拽事件来控制SingleChildScrollView的滚动,同时保留控件的点击切换功能:
import 'package:flutter/cupertino.dart'; class CustomSegmentedControl extends StatefulWidget { const CustomSegmentedControl({Key? key}) : super(key: key); @override State<CustomSegmentedControl> createState() => _CustomSegmentedControlState(); } class _CustomSegmentedControlState extends State<CustomSegmentedControl> { int? groupValue = 0; final ScrollController _scrollController = ScrollController(); @override Widget build(BuildContext context) { return SingleChildScrollView( controller: _scrollController, scrollDirection: Axis.horizontal, child: GestureDetector( // 监听水平拖拽事件,控制滚动偏移 onHorizontalDragUpdate: (DragUpdateDetails details) { _scrollController.jumpTo( _scrollController.offset - details.delta.dx, ); }, child: CupertinoSlidingSegmentedControl( padding: EdgeInsets.zero, children: const { 0: Text("Todos"), 1: Text("2005"), 2: Text("2006"), 3: Text("2007"), 4: Text("2008"), 5: Text("2009"), 6: Text("2010"), 7: Text("2011"), 8: Text("2012"), 9: Text("2013"), }, groupValue: groupValue, onValueChanged: (value) { setState(() { groupValue = value; }); }, ), ), ); } }
方案二:用Row包裹控件简化处理
将CupertinoSlidingSegmentedControl放入Row中,让SingleChildScrollView明确识别到可滚动的空间范围,部分场景下无需额外手势监听即可正常滚动:
import 'package:flutter/cupertino.dart'; class CustomSegmentedControl extends StatefulWidget { const CustomSegmentedControl({Key? key}) : super(key: key); @override State<CustomSegmentedControl> createState() => _CustomSegmentedControlState(); } class _CustomSegmentedControlState extends State<CustomSegmentedControl> { int? groupValue = 0; @override Widget build(BuildContext context) { return SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: [ CupertinoSlidingSegmentedControl( padding: EdgeInsets.zero, children: const { 0: Text("Todos"), 1: Text("2005"), 2: Text("2006"), 3: Text("2007"), 4: Text("2008"), 5: Text("2009"), 6: Text("2010"), 7: Text("2011"), 8: Text("2012"), 9: Text("2013"), }, groupValue: groupValue, onValueChanged: (value) { setState(() { groupValue = value; }); }, ), ], ), ); } }
如果方案二仍有问题,可以给SingleChildScrollView添加physics: const ClampingScrollPhysics(),替换iOS默认的弹性滚动物理效果,或结合方案一的手势监听来解决。
内容的提问来源于stack exchange,提问作者jRuMoL
相关产品推荐
相关产品推荐

