如何在Flutter中实现iOS风格带透明遮罩的滚轮时间选择器?
在Flutter中实现iOS风格的滚轮休息时间选择器(带遮罩效果)
核心实现思路
不用第三方的WheelDelegateScrollView,直接用Flutter官方提供的CupertinoPicker组件(原生适配iOS滚轮样式),再通过Stack叠加渐变遮罩来模拟iOS原生的边缘淡出效果。
完整代码示例
class RestTimePicker extends StatefulWidget { const RestTimePicker({super.key}); @override State<RestTimePicker> createState() => _RestTimePickerState(); } class _RestTimePickerState extends State<RestTimePicker> { // 默认选中1分钟 int selectedMinutes = 1; // 生成1-30分钟的选项列表 final List<int> restTimeOptions = List.generate(30, (index) => index + 1); @override Widget build(BuildContext context) { return SizedBox( // 滚轮容器高度,可根据需求调整 height: 200, child: Stack( children: [ // 核心iOS风格滚轮组件 CupertinoPicker( // 选中项放大倍数 magnification: 1.2, // 选项挤压程度,值越小越紧凑 squeeze: 1.2, // 启用选中项放大效果 useMagnifier: true, // 单个选项的高度 itemExtent: 40, // 选中项变化回调 onSelectedItemChanged: (index) { setState(() { selectedMinutes = restTimeOptions[index]; }); }, // 生成所有时间选项 children: restTimeOptions.map((time) { return Center( child: Text( '$time 分钟', style: const TextStyle(fontSize: 16), ), ); }).toList(), ), // 顶部渐变遮罩 Positioned( top: 0, left: 0, right: 0, height: 60, child: Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Colors.white.withOpacity(1), Colors.white.withOpacity(0), ], ), ), ), ), // 底部渐变遮罩 Positioned( bottom: 0, left: 0, right: 0, height: 60, child: Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.bottomCenter, end: Alignment.topCenter, colors: [ Colors.white.withOpacity(1), Colors.white.withOpacity(0), ], ), ), ), ), // 可选:选中区域上下分隔线,模拟iOS原生视觉效果 Positioned( top: 80, left: 20, right: 20, height: 1, child: Container(color: Colors.grey.shade300), ), Positioned( bottom: 80, left: 20, right: 20, height: 1, child: Container(color: Colors.grey.shade300), ), ], ), ); } }
关键细节说明
CupertinoPicker特性:自带iOS滚轮的放大、挤压效果,无需手动处理滚动逻辑,比自定义组件更贴近原生体验。- 渐变遮罩实现:通过
Stack在滚轮上层叠加两个渐变容器,顶部从完全不透明的背景色渐变到透明,底部反向渐变,实现边缘淡出的视觉效果。 - 参数调整:可以根据需求修改
itemExtent(选项高度)、magnification(放大倍数)、遮罩高度等参数,匹配设计要求。
扩展优化建议
- 若需要多列选择(如分+秒),可以使用
CupertinoPicker的多列模式,或者嵌套多个CupertinoPicker组件。 - 将遮罩封装为独立组件
WheelGradientMask,方便在多个滚轮场景中复用。 - 可结合
CupertinoActionSheet将选择器弹出,完全模拟iOS原生的选择弹窗样式。
内容的提问来源于stack exchange,提问作者Cidiko Andorem
相关产品推荐
相关产品推荐

