You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Cupertino Picker样式数字选择器?Flutter新手求助

用CupertinoPicker实现自定义数字选择器的基础思路

核心实现步骤

CupertinoPicker是Flutter原生的滚轮式选择组件,完全可以实现你需要的多列数字选择效果,基础思路如下:

  1. 生成数字数据源
    根据需求生成对应范围的数字列表,比如做小时选择就生成0-23的列表:List<int> hours = List.generate(24, (i) => i);,分钟选择则生成0-59的列表。

  2. 维护选中状态
    用StatefulWidget保存每一列的选中索引,比如int _selectedHour = 0;,后续通过选择回调更新状态。

  3. 构建多列选择器
    用Row包裹多个CupertinoPicker(每一列对应一个组件),设置itemExtent定义单个选项的高度,通过onSelectedItemChanged回调更新选中值,children里用Text渲染每个数字选项。

基础代码示例

class CustomNumberPicker extends StatefulWidget {
  const CustomNumberPicker({super.key});

  @override
  State<CustomNumberPicker> createState() => _CustomNumberPickerState();
}

class _CustomNumberPickerState extends State<CustomNumberPicker> {
  // 生成0-23小时的数字列表
  final List<int> _hours = List.generate(24, (index) => index);
  // 生成0-59分钟的数字列表
  final List<int> _minutes = List.generate(60, (index) => index);
  
  // 记录选中的小时和分钟索引
  int _selectedHour = 0;
  int _selectedMinute = 0;

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        // 小时选择列
        SizedBox(
          width: 60,
          child: CupertinoPicker(
            itemExtent: 40, // 每个选项的高度
            onSelectedItemChanged: (index) {
              setState(() => _selectedHour = index);
            },
            children: _hours.map((hour) {
              return Center(
                child: Text(
                  '$hour'.padLeft(2, '0'), // 补零显示两位数字
                  style: const TextStyle(fontSize: 18),
                ),
              );
            }).toList(),
          ),
        ),
        const Padding(
          padding: EdgeInsets.symmetric(horizontal: 8),
          child: Text(':', style: TextStyle(fontSize: 18)),
        ),
        // 分钟选择列
        SizedBox(
          width: 60,
          child: CupertinoPicker(
            itemExtent: 40,
            onSelectedItemChanged: (index) {
              setState(() => _selectedMinute = index);
            },
            children: _minutes.map((minute) {
              return Center(
                child: Text(
                  '$minute'.padLeft(2, '0'),
                  style: const TextStyle(fontSize: 18),
                ),
              );
            }).toList(),
          ),
        ),
      ],
    );
  }
}

替代方案

如果需要Material风格的滚轮选择器,可以使用第三方包(如wheel_picker),或者自定义ListView.builder实现滚轮效果,但CupertinoPicker无需额外依赖,更适合快速落地需求。

后续定制方向

  • 修改选项的字体、颜色、背景样式
  • 调整itemExtent改变选项高度
  • 用CupertinoModalPopup包裹选择器,实现底部弹出的交互效果
  • 限制数字可选范围(比如只允许选择1-12小时)
  • 添加选中项的高亮样式

内容的提问来源于stack exchange,提问作者Vedant Kakade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 21:19:54