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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 07:36:08