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

Flutter如何创建固定日期选择器时间轴?

在Flutter中创建固定日期选择器时间轴

实现思路

要实现滚动列表时日期保持固定的效果,核心是将日期选择轴与内容列表分离布局:固定日期轴的位置,让内容区域单独滚动。

代码实现示例

场景1:侧边固定日期轴(类似日程表布局)

左侧日期选择栏固定不动,右侧内容区域可垂直滚动:

import 'package:flutter/material.dart';

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

  @override
  State<FixedDateTimeline> createState() => _FixedDateTimelineState();
}

class _FixedDateTimelineState extends State<FixedDateTimeline> {
  // 模拟日期数据
  final List<String> dates = [
    '1月1日', '1月2日', '1月3日', '1月4日', '1月5日',
    '1月6日', '1月7日', '1月8日', '1月9日', '1月10日'
  ];
  
  // 选中的日期索引
  int selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: [
          // 左侧固定日期选择轴
          Container(
            width: 80,
            color: Colors.grey[100],
            child: ListView.builder(
              physics: const NeverScrollableScrollPhysics(), // 禁止滚动,保持固定
              itemCount: dates.length,
              itemBuilder: (context, index) {
                return GestureDetector(
                  onTap: () {
                    setState(() {
                      selectedIndex = index;
                    });
                  },
                  child: Container(
                    padding: const EdgeInsets.symmetric(vertical: 16),
                    alignment: Alignment.center,
                    color: selectedIndex == index ? Colors.blue[100] : Colors.transparent,
                    child: Text(
                      dates[index],
                      style: TextStyle(
                        fontWeight: selectedIndex == index ? FontWeight.bold : FontWeight.normal,
                        color: selectedIndex == index ? Colors.blue : Colors.black,
                      ),
                    ),
                  ),
                );
              },
            ),
          ),
          // 右侧可滚动内容区域
          Expanded(
            child: ListView.builder(
              itemCount: 50,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text('${dates[selectedIndex]} 事件 $index'),
                  subtitle: const Text('事件详情'),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

场景2:顶部固定日期轴(横向日期选择栏)

顶部日期栏固定,下方内容区域滚动:

import 'package:flutter/material.dart';

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

  @override
  State<TopFixedDateTimeline> createState() => _TopFixedDateTimelineState();
}

class _TopFixedDateTimelineState extends State<TopFixedDateTimeline> {
  final List<String> dates = [
    '周一', '周二', '周三', '周四', '周五', '周六', '周日'
  ];
  int selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          // 顶部固定日期选择轴
          Container(
            height: 60,
            color: Colors.grey[100],
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              itemCount: dates.length,
              itemBuilder: (context, index) {
                return GestureDetector(
                  onTap: () {
                    setState(() {
                      selectedIndex = index;
                    });
                  },
                  child: Container(
                    padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
                    margin: const EdgeInsets.symmetric(horizontal: 4),
                    decoration: BoxDecoration(
                      color: selectedIndex == index ? Colors.blue : Colors.transparent,
                      borderRadius: BorderRadius.circular(20),
                    ),
                    child: Text(
                      dates[index],
                      style: TextStyle(
                        color: selectedIndex == index ? Colors.white : Colors.black,
                      ),
                    ),
                  ),
                );
              },
            ),
          ),
          // 下方可滚动内容区域
          Expanded(
            child: ListView.builder(
              itemCount: 30,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text('${dates[selectedIndex]} 任务 $index'),
                  subtitle: const Text('任务描述'),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

关键要点

  • 侧边固定场景中,给日期轴的ListView设置NeverScrollableScrollPhysics()禁止滚动,确保位置固定。
  • 通过setState更新选中日期的样式,强化交互反馈。
  • 内容区域用Expanded包裹ListView,确保占满剩余空间并支持滚动。

内容的提问来源于stack exchange,提问作者Flutter kyoto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:50:22