You need to enable JavaScript to run this app. 如何在Flutter中实现如图所示的可滚动日历功能
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中实现如图所示的可滚动日历功能

Flutter 可滚动日历实现方案

方案一:基于现有插件二次开发(推荐)

优先使用Flutter生态中成熟的table_calendar插件,该插件支持极高的自定义度,无需从零开发即可满足绝大多数设计需求:

  • 开启滚动/无限滚动:配置pageScrollPhysics参数实现顺滑翻页,通过设置firstDay、lastDay覆盖需要的年份范围即可实现无限滚动效果
  • 自定义样式:通过calendarBuilders属性自定义日期单元格、周标题、头部导航的所有视觉样式,完全对齐设计稿
  • 内置交互支持:默认支持日期单选、区间选择、多日期选择等常用交互,可直接配置启用

方案二:手动实现核心逻辑(适用于高度定制场景)

如果插件无法满足特殊交互需求,可按以下三个模块拆分实现:

1. 日期数据计算模块

编写工具方法,传入目标年月即可生成当月需要展示的完整日期列表(包含上月末尾、当月、下月开头的补位日期,兼容周起始日配置):

/// 生成指定月份的日历展示日期列表,默认周起始为周一
List<DateTime> generateMonthCalendar(int year, int month, {int weekStart = 1}) {
  final firstDayOfMonth = DateTime(year, month, 1);
  // 计算当月第一天前需要补的上月日期数量
  final leadingDays = (firstDayOfMonth.weekday - weekStart) % 7;
  final firstShowDay = firstDayOfMonth.subtract(Duration(days: leadingDays));
  // 固定生成6行共42个日期,兼容所有月份的展示需求
  return List.generate(42, (index) => firstShowDay.add(Duration(days: index)));
}

2. 滚动容器实现

用PageView作为滚动容器,通过初始页偏移实现近似无限滚动效果:

final now = DateTime.now();

PageView.builder(
  // 初始页设置为较大中间值,左右滚动都有足够的预留空间
  controller: PageController(initialPage: 1000),
  onPageChanged: (index) {
    // 计算当前页面对应的年月
    final monthOffset = index - 1000;
    final currentShowDate = DateTime(now.year, now.month + monthOffset);
    // 此处更新当前展示年月的状态即可
  },
  itemBuilder: (context, index) {
    final monthOffset = index - 1000;
    final targetDate = DateTime(now.year, now.month + monthOffset);
    final dateList = generateMonthCalendar(targetDate.year, targetDate.month);
    // 构建当月日期网格
    return GridView.count(
      physics: const NeverScrollableScrollPhysics(),
      crossAxisCount: 7,
      padding: EdgeInsets.zero,
      children: dateList.map((date) {
        // 自定义日期单元格样式
        return Container(
          alignment: Alignment.center,
          padding: const EdgeInsets.symmetric(vertical: 8),
          child: Text(
            date.day.toString(),
            style: TextStyle(
              color: date.month == targetDate.month ? Colors.black87 : Colors.grey.shade400,
            ),
          ),
        );
      }).toList(),
    );
  },
)

3. 交互扩展

在上述基础上,增加点击选中、区间高亮、特殊日期标记等交互逻辑,只需要对应维护选中状态、在单元格构造时判断当前日期的状态返回对应样式即可。


内容的提问来源于stack exchange,提问作者Farrukh Zokirov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 18:27:04