如何在Flutter中实现可横向滚动的日期列表功能?
Flutter横向滚动日期列表实现方案
1. 核心组件选型
- 横向滚动容器直接用
ListView.builder,设置scrollDirection: Axis.horizontal即可实现,无需引入第三方依赖 - 日期计算直接用Dart内置
DateTime类,支持日期偏移、星期/日期属性获取,完全满足需求
2. 单日期项UI实现
每个日期项包含选中态背景、星期文本、日期数字三层,选中态通过状态变量控制样式变化即可,示例代码如下:
Widget _buildDateItem(DateTime date, bool isSelected) { return Container( width: 60, margin: const EdgeInsets.symmetric(horizontal: 4), decoration: BoxDecoration( color: isSelected ? Colors.blue : Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey.shade200), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( ['周一', '周二', '周三', '周四', '周五', '周六', '周日'][date.weekday - 1], style: TextStyle( color: isSelected ? Colors.white : Colors.grey, fontSize: 12, ), ), const SizedBox(height: 4), Text( date.day.toString(), style: TextStyle( color: isSelected ? Colors.white : Colors.black87, fontSize: 16, fontWeight: FontWeight.w500, ), ), ], ), ); }
3. 横向列表整体实现
可以自定义展示的日期范围,比如默认展示前后30天、默认选中当日,完整示例代码如下:
class HorizontalDatePicker extends StatefulWidget { const HorizontalDatePicker({super.key, required this.onDateSelected}); // 选中日期回调 final Function(DateTime) onDateSelected; @override State<HorizontalDatePicker> createState() => _HorizontalDatePickerState(); } class _HorizontalDatePickerState extends State<HorizontalDatePicker> { DateTime selectedDate = DateTime.now(); // 总共展示60天日期:往前30天+往后30天 final int totalShowDays = 60; final int beforeTodayCount = 30; @override Widget build(BuildContext context) { return SizedBox( height: 80, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: totalShowDays, itemBuilder: (context, index) { DateTime itemDate = DateTime.now().add(Duration(days: index - beforeTodayCount)); bool isSelected = itemDate.year == selectedDate.year && itemDate.month == selectedDate.month && itemDate.day == selectedDate.day; return GestureDetector( onTap: () { setState(() { selectedDate = itemDate; }); widget.onDateSelected(itemDate); }, child: _buildDateItem(itemDate, isSelected), ); }, ), ); } }
4. 可选优化点
- 需要默认滚动到当前选中日期位置的话,给
ListView.builder添加ScrollController,初始化时调用animateTo定位到对应索引的位置即可 - 需要展示月份分组的话,可以在列表中插入分组头,判断日期跨月时渲染对应月份的提示文本
ListView.builder本身支持懒加载,哪怕展示数百天的日期也不会出现性能卡顿
内容的提问来源于stack exchange,提问作者developerTobi
相关产品推荐
相关产品推荐

