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

如何在showDatePicker中高亮节假日与周末?

在Flutter的showDatePicker中高亮节假日与周末

Flutter自带的showDatePicker没有直接提供高亮节假日和周末的配置项,需要通过自定义日期单元格样式实现,核心是利用其builder参数覆盖默认日历组件的显示逻辑。

实现步骤

  1. 准备节假日列表与判断方法
    先定义节假日集合,以及判断周末、节假日的工具方法:
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));
}
  1. 自定义日期单元格样式
    通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 23:27:45