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

Flutter中如何为CupertinoDatePicker设置自定义日期格式?

解决CupertinoDatePicker自定义日期显示格式的问题

原生CupertinoDatePicker确实没有直接提供自定义完整日期显示格式的参数,仅能通过dateOrder调整年、月、日的排列顺序,或通过mode切换日期/时间模式,无法满足显示Monday, April 10, 2024这类包含星期、月份全称的格式需求。要在选择器UI中直接展示该格式,你可以通过以下两种方式实现:


方式一:自定义单滚轮完整日期选择器

如果希望选择器的滚轮直接显示完整格式的日期选项,可以自己基于CupertinoPicker构建:

首先需要导入intl包(用于日期格式化),在pubspec.yaml中添加:

dependencies:
  intl: ^0.18.1

然后实现自定义选择器:

class CustomFullDatePicker extends StatefulWidget {
  final DateTime initialDate;
  final ValueChanged<DateTime> onDateChanged;
  final DateTime? minDate;
  final DateTime? maxDate;

  const CustomFullDatePicker({
    super.key,
    required this.initialDate,
    required this.onDateChanged,
    this.minDate,
    this.maxDate,
  });

  @override
  State<CustomFullDatePicker> createState() => _CustomFullDatePickerState();
}

class _CustomFullDatePickerState extends State<CustomFullDatePicker> {
  late DateTime _selectedDate;
  late List<String> _fullDateOptions;
  final DateFormat _dateFormatter = DateFormat('EEEE, MMMM dd, yyyy');

  @override
  void initState() {
    super.initState();
    _selectedDate = widget.initialDate;
    _generateFullDateOptions();
  }

  // 生成指定范围内的完整格式日期选项
  void _generateFullDateOptions() {
    _fullDateOptions = [];
    final startDate = widget.minDate ?? DateTime.now().subtract(const Duration(days: 365 * 3));
    final endDate = widget.maxDate ?? DateTime.now().add(const Duration(days: 365 * 3));

    for (var date = startDate; date.isBefore(endDate.add(const Duration(days: 1))); date = date.add(const Duration(days: 1))) {
      _fullDateOptions.add(_dateFormatter.format(date));
    }
  }

  @override
  Widget build(BuildContext context) {
    final selectedIndex = _fullDateOptions.indexOf(_dateFormatter.format(_selectedDate));

    return CupertinoPicker(
      magnification: 1.2,
      squeeze: 1.2,
      useMagnifier: true,
      itemExtent: 32,
      scrollController: FixedExtentScrollController(initialItem: selectedIndex),
      onSelectedItemChanged: (index) {
        final parsedDate = _dateFormatter.parse(_fullDateOptions[index]);
        setState(() => _selectedDate = parsedDate);
        widget.onDateChanged(parsedDate);
      },
      children: _fullDateOptions.map((dateStr) {
        return Center(child: Text(dateStr, style: const TextStyle(fontSize: 16)));
      }).toList(),
    );
  }
}

使用示例:

void _showCustomPicker() {
  showCupertinoModalPopup(
    context: context,
    builder: (context) => Container(
      height: 280,
      color: CupertinoColors.white,
      child: Column(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              CupertinoButton(
                child: const Text('Done'),
                onPressed: () => Navigator.pop(context),
              ),
            ],
          ),
          const Divider(height: 0),
          Expanded(
            child: CustomFullDatePicker(
              initialDate: DateTime.now(),
              onDateChanged: (selectedDate) {
                // 处理选中的日期
              },
            ),
          ),
        ],
      ),
    ),
  );
}

方式二:保留原生多滚轮,顶部显示完整格式

如果想保留原生CupertinoDatePicker的多滚轮交互,同时在选择器UI内显示完整格式的选中日期,可以在选择器上方添加实时更新的文本:

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

  @override
  State<DatePickerWithFullDisplay> createState() => _DatePickerWithFullDisplayState();
}

class _DatePickerWithFullDisplayState extends State<DatePickerWithFullDisplay> {
  DateTime _selectedDate = DateTime.now();
  final DateFormat _fullFormatter = DateFormat('EEEE, MMMM dd, yyyy');

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // 顶部显示完整格式的选中日期
        Padding(
          padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20),
          child: Text(
            _fullFormatter.format(_selectedDate),
            style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
          ),
        ),
        const Divider(height: 0),
        Expanded(
          child: CupertinoDatePicker(
            initialDateTime: _selectedDate,
            onDateTimeChanged: (newDate) {
              setState(() => _selectedDate = newDate);
            },
            mode: CupertinoDatePickerMode.date,
            minimumDate: DateTime.now().subtract(const Duration(days: 365 * 3)),
            maximumDate: DateTime.now().add(const Duration(days: 365 * 3)),
          ),
        ),
      ],
    );
  }
}

内容的提问来源于stack exchange,提问作者Roy Krueger

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 22:48:15