如何在Flutter中用RadioButton实现日期筛选器(DateFilters)
Flutter日期筛选器实现方案
1. 定义筛选时段枚举
先把常用的筛选选项封装成枚举,方便统一管理:
enum DateFilterType { thisWeek, lastWeek, thisMonth, lastMonth, customRange, }
2. 实现日期范围计算逻辑
针对每个筛选类型,编写对应的日期范围计算方法,以本周、上周为例:
class DateFilterUtil { // 获取本周(周一至周日)的起止日期 static (DateTime start, DateTime end) getThisWeekRange() { final now = DateTime.now(); // Flutter中DateTime.weekday周一为1,周日为7,计算距离周一的天数 final daysToMonday = now.weekday - 1; final startOfWeek = DateTime(now.year, now.month, now.day - daysToMonday); final endOfWeek = startOfWeek.add(const Duration(days: 6)); // 统一设置为当天0点和23:59:59,避免时间部分干扰筛选 return ( DateTime(startOfWeek.year, startOfWeek.month, startOfWeek.day), DateTime(endOfWeek.year, endOfWeek.month, endOfWeek.day, 23, 59, 59) ); } // 获取上周的起止日期 static (DateTime start, DateTime end) getLastWeekRange() { final thisWeekStart = getThisWeekRange().$1; final lastWeekStart = thisWeekStart.subtract(const Duration(days: 7)); final lastWeekEnd = lastWeekStart.add(const Duration(days: 6)); return ( DateTime(lastWeekStart.year, lastWeekStart.month, lastWeekStart.day), DateTime(lastWeekEnd.year, lastWeekEnd.month, lastWeekEnd.day, 23, 59, 59) ); } // 同理可实现本月、上月的范围计算逻辑 }
3. 数据筛选核心方法
基于计算出的日期范围,对数据源进行筛选(假设数据模型包含DateTime createdAt字段):
List<YourDataModel> filterDataByRange(List<YourDataModel> data, DateTime start, DateTime end) { return data.where((item) { // 加1秒避免刚好等于end时间的数据被遗漏 return item.createdAt.isAfter(start) && item.createdAt.isBefore(end.add(const Duration(seconds: 1))); }).toList(); }
4. UI交互与状态更新
用下拉菜单或自定义筛选组件让用户选择时段,结合StatefulWidget实现筛选结果实时更新:
class DateFilterPage extends StatefulWidget { const DateFilterPage({super.key}); @override State<DateFilterPage> createState() => _DateFilterPageState(); } class _DateFilterPageState extends State<DateFilterPage> { DateFilterType _selectedFilter = DateFilterType.thisWeek; List<YourDataModel> _filteredData = []; final List<YourDataModel> _originalData = []; // 替换为你的原始数据源 @override void initState() { super.initState(); _refreshFilteredData(); } void _refreshFilteredData() { late (DateTime start, DateTime end) dateRange; switch (_selectedFilter) { case DateFilterType.thisWeek: dateRange = DateFilterUtil.getThisWeekRange(); break; case DateFilterType.lastWeek: dateRange = DateFilterUtil.getLastWeekRange(); break; // 补充其他筛选类型的分支 } setState(() { _filteredData = filterDataByRange(_originalData, dateRange.start, dateRange.end); }); } @override Widget build(BuildContext context) { return Column( children: [ DropdownButton<DateFilterType>( value: _selectedFilter, items: const [ DropdownMenuItem( value: DateFilterType.thisWeek, child: Text("本周"), ), DropdownMenuItem( value: DateFilterType.lastWeek, child: Text("上周"), ), // 添加其他筛选选项 ], onChanged: (value) { if (value != null) { setState(() => _selectedFilter = value); _refreshFilteredData(); } }, ), // 展示筛选后的数据列表 Expanded( child: ListView.builder( itemCount: _filteredData.length, itemBuilder: (context, index) { return ListTile( title: Text(_filteredData[index].title), subtitle: Text(_filteredData[index].createdAt.toString().split(" ")[0]), ); }, ), ), ], ); } }
关键注意事项
- 时区处理:如果数据源是UTC时间,需要先转换为本地时间再筛选,避免时差导致的筛选错误。
- 自定义范围:若需支持自定义日期区间,可使用
showDatePicker让用户选择起止日期,再调用筛选方法。
内容的提问来源于stack exchange,提问作者Umar Saidu
相关产品推荐
相关产品推荐

