求助:如何在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
相关产品推荐
相关产品推荐

