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

求助:如何在Flutter中实现指定样式的水平日历

Flutter 水平日历实现(带当日高亮)

自定义实现代码

以下是直接可用的Flutter代码,实现水平滚动日历并自动高亮当前日期:

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

class HorizontalCalendar extends StatefulWidget {
  const HorizontalCalendar({super.key});

  @override
  State<HorizontalCalendar> createState() => _HorizontalCalendarState();
}

class _HorizontalCalendarState extends State<HorizontalCalendar> {
  // 生成前后15天共30天的日期列表,可按需调整范围
  final List<DateTime> _dates = List.generate(30, (index) {
    return DateTime.now().subtract(Duration(days: 15 - index));
  });

  // 默认选中今日
  DateTime _selectedDate = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 80,
      child: ListView.builder(
        scrollDirection: Axis.horizontal,
        padding: const EdgeInsets.symmetric(horizontal: 16),
        itemCount: _dates.length,
        itemBuilder: (context, index) {
          final date = _dates[index];
          final isToday = DateFormat('yyyyMMdd').format(date) == DateFormat('yyyyMMdd').format(DateTime.now());
          final isSelected = DateFormat('yyyyMMdd').format(date) == DateFormat('yyyyMMdd').format(_selectedDate);
          
          // 样式优先级:选中状态>今日>普通日期
          final bgColor = isSelected 
              ? Colors.blue 
              : isToday 
                  ? Colors.blue.withOpacity(0.2) 
                  : Colors.transparent;
          final textColor = isSelected || isToday ? Colors.blue : Colors.grey;

          return GestureDetector(
            onTap: () => setState(() => _selectedDate = date),
            child: Container(
              margin: const EdgeInsets.symmetric(horizontal: 8),
              padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
              decoration: BoxDecoration(
                color: bgColor,
                borderRadius: BorderRadius.circular(20),
              ),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(
                    DateFormat('EEE').format(date),
                    style: TextStyle(
                      fontSize: 12,
                      color: textColor,
                      fontWeight: isSelected || isToday ? FontWeight.w600 : FontWeight.normal,
                    ),
                  ),
                  const SizedBox(height: 4),
                  Text(
                    DateFormat('d').format(date),
                    style: TextStyle(
                      fontSize: 16,
                      color: textColor,
                      fontWeight: isSelected || isToday ? FontWeight.bold : FontWeight.normal,
                    ),
                  ),
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}

// 使用示例
void main() {
  runApp(const MaterialApp(
    home: Scaffold(
      appBar: AppBar(title: Text('水平日历示例')),
      body: Column(
        children: [
          SizedBox(height: 20),
          HorizontalCalendar(),
        ],
      ),
    ),
  ));
}

核心实现逻辑

  • 日期范围生成:通过List.generate快速生成指定天数的日期列表,可自行调整前后天数
  • 高亮判断:用DateFormat统一格式化日期字符串,精准对比当日和选中日期
  • 交互逻辑:点击日期时更新选中状态,触发UI重绘切换样式
  • 样式区分:通过三元表达式分别定义普通、当日、选中状态的背景色与文字样式

第三方包替代方案

如果不想自定义开发,可直接使用成熟的日历包快速实现:

  • table_calendar:支持切换为水平滚动模式,可通过calendarStyle配置当日高亮样式
  • flutter_calendar_carousel:原生支持水平滚动布局,内置多种样式配置项

使用第三方包时,只需在pubspec.yaml中添加依赖,再根据官方文档配置高亮规则即可。

内容的提问来源于stack exchange,提问作者Meet Sonchhatra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 13:42:40