如何在Flutter/Dart中基于DateTime和TimeOfDay对列表项排序
问题根源
你当前的写法连续执行3次独立的sort排序,后一次排序会完全覆盖前一次的排序逻辑,仅保留最后一次的排序结果。比如你先按日期排序完成后,再按小时排序时,会忽略日期差异,把不同日期但小时相同的任务混排,最终结果自然不符合预期。
最优实现方案
方案1:合并为完整DateTime比较(最简洁)
直接将任务的日期和时间拼接为完整的DateTime对象,一次比较即可得出结果,代码可读性高且不易出错:
_tasks.sort((a, b) { // 拼接a的完整时间 final aDateTime = DateTime( a.date!.year, a.date!.month, a.date!.day, a.time!.hour, a.time!.minute ); // 拼接b的完整时间 final bDateTime = DateTime( b.date!.year, b.date!.month, b.date!.day, b.time!.hour, b.time!.minute ); // 升序排列,如需降序改为 bDateTime.compareTo(aDateTime) return aDateTime.compareTo(bDateTime); });
方案2:分层优先级比较
如果不需要拼接完整时间,可以在同一个排序回调内按优先级分层比较,效果和方案1完全一致:
_tasks.sort((a, b) { // 优先级1:先比较日期 final dateDiff = a.date!.compareTo(b.date!); if (dateDiff != 0) return dateDiff; // 优先级2:日期相同比较小时 final hourDiff = a.time!.hour.compareTo(b.time!.hour); if (hourDiff != 0) return hourDiff; // 优先级3:小时相同比较分钟 return a.time!.minute.compareTo(b.time!.minute); });
可选拓展:空值&状态兼容
如果你的业务中存在date或time为空的场景,或者需要把未完成任务排到前面,可以加上对应判断逻辑:
_tasks.sort((a, b) { // 优先级0:未完成任务排前面 if (a.isFinished != b.isFinished) { return a.isFinished ? 1 : -1; } // 空日期处理:空值排到列表末尾 if (a.date == null && b.date == null) return 0; if (a.date == null) return 1; if (b.date == null) return -1; // 空时间处理:同日期下空时间排末尾 if (a.time == null && b.time == null) return 0; if (a.time == null) return 1; if (b.time == null) return -1; // 正常比较时间 final aDateTime = DateTime(a.date!.year, a.date!.month, a.date!.day, a.time!.hour, a.time!.minute); final bDateTime = DateTime(b.date!.year, b.date!.month, b.date!.day, b.time!.hour, b.time!.minute); return aDateTime.compareTo(bDateTime); });
内容的提问来源于stack exchange,提问作者MhdBasilE
相关产品推荐
相关产品推荐

