如何在showDatePicker中高亮节假日与周末?
在Flutter的showDatePicker中高亮节假日与周末
Flutter自带的showDatePicker没有直接提供高亮节假日和周末的配置项,需要通过自定义日期单元格样式实现,核心是利用其builder参数覆盖默认日历组件的显示逻辑。
实现步骤
- 准备节假日列表与判断方法
先定义节假日集合,以及判断周末、节假日的工具方法:
import 'package:flutter/material.dart'; // 示例节假日列表 final List<DateTime> holidays = [ DateTime(2024, 1, 1), DateTime(2024, 2, 10), // 添加更多节假日... ]; // 判断是否为周末 bool isWeekend(DateTime date) { return date.weekday == DateTime.saturday || date.weekday == DateTime.sunday; } // 判断是否为节假日(用isSameDay忽略时分秒差异) bool isHoliday(DateTime date) { return holidays.any((holiday) => isSameDay(holiday, date)); }
- 自定义日期单元格样式
通过showDatePicker的builder参数,替换内部的CalendarDatePicker并自定义每个日期的UI:
showDatePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime(2024), lastDate: DateTime(2025), builder: (context, child) { if (child is CalendarDatePicker) { return CalendarDatePicker( initialDate: child.initialDate, firstDate: child.firstDate, lastDate: child.lastDate, onDateChanged: child.onDateChanged, // 自定义每个日期单元格 dayBuilder: (context, date) { final bool isSelected = isSameDay(child.selectedDate, date); final bool isToday = isSameDay(DateTime.now(), date); final bool isWeekendDate = isWeekend(date); final bool isHolidayDate = isHoliday(date); // 配置样式 Color bgColor = Colors.transparent; TextStyle textStyle = const TextStyle(color: Colors.black87); if (isSelected) { // 保留选中状态默认样式 bgColor = Theme.of(context).colorScheme.primary; textStyle = const TextStyle(color: Colors.white); } else if (isToday) { // 保留今日默认样式 bgColor = Theme.of(context).colorScheme.primary.withOpacity(0.1); } else if (isHolidayDate) { // 节假日高亮样式 bgColor = Colors.red.withOpacity(0.2); textStyle = const TextStyle(color: Colors.red); } else if (isWeekendDate) { // 周末高亮样式 bgColor = Colors.blue.withOpacity(0.1); textStyle = const TextStyle(color: Colors.blue); } return Container( margin: const EdgeInsets.all(4), decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(8), ), child: Center( child: Text( date.day.toString(), style: textStyle, ), ), ); }, ); } return child!; }, );
兼容低版本Flutter
如果你的Flutter版本没有CalendarDatePicker的dayBuilder参数,可以通过修改全局主题实现:
builder: (context, child) { return Theme( data: Theme.of(context).copyWith( calendarTheme: CalendarTheme( dayDecoration: (context, date, isSelected, isToday) { Color? bgColor; if (isHoliday(date)) { bgColor = Colors.red.withOpacity(0.2); } else if (isWeekend(date)) { bgColor = Colors.blue.withOpacity(0.1); } return BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(8), ); }, dayStyle: const TextStyle(color: Colors.black87), ), ), child: child!, ); }
注意事项
- 必须用
isSameDay判断日期相等,避免因DateTime的时分秒差异导致判断错误。 - 可根据需求调整高亮的颜色、圆角、边距等样式,适配自身UI设计。
内容的提问来源于stack exchange,提问作者hok khai
相关产品推荐
相关产品推荐

