Flutter Table Calendar年份选择方法及切换年份选择选项
在Flutter Table Calendar中实现年份选择与视图切换
1. 基础配置:管理视图状态
因为你隐藏了默认的格式切换按钮(formatButtonVisible: false),所以需要手动通过状态变量控制日历的显示格式:
class _YourWidgetState extends State<YourWidget> { CalendarFormat _calendarFormat = CalendarFormat.month; DateTime _focusedDay = DateTime.now(); DateTime? _selectedDay; @override Widget build(BuildContext context) { return TableCalendar( headerStyle: const HeaderStyle( formatButtonVisible: false, titleCentered: true, ), firstDay: DateTime.utc(2010, 10, 16), lastDay: DateTime.utc(2030, 3, 14), focusedDay: _focusedDay, selectedDayPredicate: (day) => isSameDay(_selectedDay, day), // 绑定当前视图格式 calendarFormat: _calendarFormat, // 切换视图时更新状态 onFormatChanged: (format) { setState(() { _calendarFormat = format; }); }, onDaySelected: (selectedDay, focusedDay) { setState(() { _selectedDay = selectedDay; _focusedDay = focusedDay; }); // 区分视图类型处理选中逻辑 if (_calendarFormat == CalendarFormat.year) { // 年视图下,selectedDay为选中年份的1月1日,直接取year值 String selectedYear = selectedDay.year.toString(); controllerTtl.text = selectedYear; Navigator.pop(context); } else { controllerTtl.text = selectedDay.toString().substring(0, 10); Navigator.pop(context); } }, // 可选:限制仅显示月、年两种视图 availableCalendarFormats: const { CalendarFormat.month: '月', CalendarFormat.year: '年', }, ); } }
2. 实现年份选择
- 默认交互方式:点击日历头部的标题(如当前月份),会逐级切换视图:
月视图 → 年视图(受availableCalendarFormats限制)。切换到年视图后,点击任意年份即可触发onDaySelected回调,通过selectedDay.year获取选中的年份。 - 主动触发年份视图:如果需要通过外部按钮直接打开年份选择视图,更新状态即可:
ElevatedButton( onPressed: () { setState(() { _calendarFormat = CalendarFormat.year; }); }, child: const Text('切换到年份选择'), )
3. 自定义年份切换选项
如果需要完全自定义头部的切换交互,可以替换默认标题为自定义可点击组件:
headerStyle: HeaderStyle( formatButtonVisible: false, titleCentered: true, titleWidget: GestureDetector( onTap: () { setState(() { // 在月、年视图间切换 _calendarFormat = _calendarFormat == CalendarFormat.year ? CalendarFormat.month : CalendarFormat.year; }); }, child: Text( _calendarFormat == CalendarFormat.year ? '选择年份' : '${_focusedDay.year}年${_focusedDay.month}月', style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ), ),
内容的提问来源于stack exchange,提问作者AMA
相关产品推荐
相关产品推荐

