import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import '../core/theme/context_tokens.dart'; import '../core/theme/app_dims.g.dart'; import '../core/responsive/responsive.dart'; import '../core/utils/dialog_util.dart'; /// 年/月/日 滚轮日期选择器(对齐原型 .wheel-pop)。选中返回 DateTime,取消返回 null。 /// 「今天」快速跳到今天;「确定」确认。范围选择由调用方调两次(起/止)拼成。 Future showWheelDatePicker( BuildContext context, { DateTime? initial, String title = '选择日期', }) { return showAppDialog( context: context, builder: (_) => _WheelDateDialog(initial: initial ?? DateTime.now(), title: title), ); } class _WheelDateDialog extends StatefulWidget { final DateTime initial; final String title; const _WheelDateDialog({required this.initial, required this.title}); @override State<_WheelDateDialog> createState() => _WheelDateDialogState(); } class _WheelDateDialogState extends State<_WheelDateDialog> { late DateTime _value; @override void initState() { super.initState(); _value = DateTime(widget.initial.year, widget.initial.month, widget.initial.day); } @override Widget build(BuildContext context) { final t = context.tokens; return Dialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(AppDims.rXl)), child: SizedBox( width: context.dialogWidth(320), child: Column( mainAxisSize: MainAxisSize.min, children: [ Padding( padding: const EdgeInsets.fromLTRB(16, 14, 16, 4), child: Row( children: [ Text(widget.title, style: TextStyle( fontSize: AppDims.fsTitle, fontWeight: FontWeight.w600, color: t.heading)), ], ), ), // 三列滚轮(年/月/日),中间高亮行由 CupertinoDatePicker 提供。 SizedBox( height: 200, child: CupertinoTheme( data: CupertinoThemeData( textTheme: CupertinoTextThemeData( dateTimePickerTextStyle: TextStyle(fontSize: 18, color: t.text), ), ), child: CupertinoDatePicker( mode: CupertinoDatePickerMode.date, initialDateTime: _value, minimumYear: 2015, maximumYear: 2035, onDateTimeChanged: (d) => _value = DateTime(d.year, d.month, d.day), ), ), ), const Divider(height: 1), Padding( padding: const EdgeInsets.fromLTRB(12, 8, 12, 10), child: Row( children: [ TextButton( onPressed: () { final now = DateTime.now(); setState(() => _value = DateTime(now.year, now.month, now.day)); }, child: Text('今天', style: TextStyle(color: t.muted)), ), const Spacer(), TextButton( onPressed: () => Navigator.of(context).pop(), child: Text('取消', style: TextStyle(color: t.muted)), ), const SizedBox(width: 4), ElevatedButton( onPressed: () => Navigator.of(context).pop(_value), style: ElevatedButton.styleFrom( backgroundColor: t.primary, foregroundColor: t.onPrimary, elevation: 0, ), child: const Text('确定'), ), ], ), ), ], ), ), ); } } /// 范围选择:先选起始日、再选结束日;任一取消则返回 null。 Future showWheelDateRange( BuildContext context, { DateTimeRange? initial, }) async { final start = await showWheelDatePicker(context, initial: initial?.start, title: '起始日期'); if (start == null || !context.mounted) return null; final end = await showWheelDatePicker(context, initial: initial?.end ?? start, title: '结束日期'); if (end == null) return null; // 保证 start <= end return end.isBefore(start) ? DateTimeRange(start: end, end: start) : DateTimeRange(start: start, end: end); }