Flutter 日期范围筛选组件全解析:timeCop项目DateRangeTile + FilterPreset + CloneTime


一、整体功能概述


在许多应用中(如时间追踪、任务管理、统计报表等),用户需要筛选特定时间段的数据。
这个组件体系提供了:

  • 可折叠的筛选面板;

  • 快捷预设日期(本周、本月、上月、最近 X 天);

  • 自定义起止日期选择;

  • 国际化支持;

  • Bloc 状态管理集成。

整个功能可以用一句话概括:

“一个轻量、通用、可扩展的日期范围筛选控件”


⚙️ 二、核心模块结构

组件体系包含三个核心模块:

模块名作用文件来源
DateRangeTile主 UI 组件,展示和处理日期选择date_range_tile.dart
FilterPreset定义快捷日期范围逻辑filter_preset.dart
CloneTime扩展 DateTime 的克隆能力clone_time.dart

下面我们逐个分析👇


🧩 三、DateRangeTile — UI 控件主体

🧠 功能简介

这是整个日期筛选功能的视觉与交互核心。

  • 采用 ExpansionTile 实现可折叠结构;

  • 展示一组 ActionChip 作为快捷筛选;

  • 两个 ListTile 负责手动选择“起始日期”和“结束日期”;

  • 支持清除、国际化、Bloc 默认配置。


📜 逻辑流程

graph TD
A[展开筛选面板] --> B[选择快捷预设]
A --> C[手动选择起始日期]
A --> D[手动选择结束日期]
B --> E[更新 startDate/endDate 回调]
C --> E
D --> E
E --> F[父组件通过 onStartChosen/onEndChosen 更新状态]

🧩 核心结构解析

return ExpansionTile(
  title: Text(L10N.of(context).tr.filter, ...),
  initiallyExpanded: initiallyExpanded,
  children: [
    _buildFilterPresets(), // 快捷预设
    _buildStartDateTile(), // 起始日期
    _buildEndDateTile(),   // 结束日期
  ],
);
  • ExpansionTile:负责折叠结构与标题;

  • FilterPreset:生成一行 ActionChip

  • ListTile:展示当前起止日期和清除按钮。


⏰ 日期选择逻辑

使用 flutter_datetime_picker_plus 代替系统默认的 showDatePicker

await dt.DatePicker.showDatePicker(
  context,
  currentTime: startDate,
  onConfirm: (dt) => onStartChosen(DateTime(dt.year, dt.month, dt.day)),
  onCancel: () => onStartChosen(oldStartDate),
  theme: dt.DatePickerTheme(...),
);

✅ 这种方式允许自定义主题色、取消样式,UI 更统一。


🧹 知识点

  • 自动补齐时间精度

    • 起始日期设为 00:00:00

    • 结束日期设为 23:59:59.999

  • 支持清除按钮

    • 用户可点击圆形减号图标清空选中日期;

  • 支持国际化

    • 所有文字通过 L10N.of(context).tr.xxx 获取;

  • 默认展开控制

    • 通过 initiallyExpanded 决定折叠状态。


🔢 四、FilterPreset — 日期范围枚举逻辑

🧠 功能说明

这是日期预设的逻辑层定义,用于提供几种常用的时间段选项:

enum FilterPreset {
  thisWeek,
  thisMonth,
  lastMonth,
  lastXDays;
}

这些选项会被映射为 ActionChip 按钮。


📅 核心逻辑分析

1️⃣ 获取起始时间
DateTime getStartDate(int firstDayOfWeekIndex, int defaultFilterDays)

不同选项对应不同算法:

  • thisWeek:计算本周第一天(考虑周起始日差异);

  • thisMonth:返回当月第一天;

  • lastMonth:返回上月第一天;

  • lastXDays:返回最近 X 天的起点。

🔍 注意:firstDayOfWeekIndex 来源于 MaterialLocalizations,可自动适配区域(例如周一或周日为一周起点)。


2️⃣ 获取结束时间
DateTime? getEndDate()

部分选项返回 null(表示截止到当前时间),部分返回上月末/本月末:

  • thisWeeklastXDaysnull

  • thisMonth → 下月第一天减一秒

  • lastMonth → 本月第一天减一秒


3️⃣ 获取展示文案
String display(BuildContext context, int defaultFilterDays)

通过 L10N 国际化资源动态显示:

  • This Week / 本周

  • This Month / 本月

  • Last Month / 上月

  • Last X Days / 最近 N 天(动态填充 N


🧩 五、CloneTime — DateTime 扩展工具

🧠 功能说明

DateTime 本身是不可变对象,但在日期选择中有时需要复制一个旧值做恢复用。
CloneTime 扩展提供一个简洁方法:

extension CloneTime on DateTime {
  DateTime clone() => DateTime(year, month, day, hour, minute, second, millisecond, microsecond);
}

✅ 用于在取消日期选择时恢复原始状态,例如:

final oldStartDate = startDate?.clone();

🔁 六、完整逻辑执行顺序

步骤动作结果
1用户展开组件显示快捷预设和日期选择
2点击快捷预设自动计算起止时间并更新状态
3点击起始日期弹出日期选择器(保存 oldStartDate)
4确认选择回调更新父组件的 startDate
5取消选择恢复 oldStartDate
6点击结束日期同上,补齐到 23:59:59.999
7点击清除图标将日期设为 null

🎨 七、视觉与交互细节

元素用途组件
过滤标题展示“Filter”字样Text
快捷预设横向滑动选择SingleChildScrollView + Row + ActionChip
日期项显示当前日期或 "--"ListTile
清除按钮清空日期IconButton
日期选择弹窗选中日期flutter_datetime_picker_plus

💡 


🧭 八、总结(Conclusion)

  • 结构清晰:UI、逻辑、工具分层;

  • 可配置性强:支持 Bloc、国际化、多种预设;

  • 体验友好:清除、取消、补齐时间、横向滑动;

  • 易扩展:添加更多预设、约束或样式都很方便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值