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
相关产品推荐
相关产品推荐

