Dart日程系统:当前与下一对课程高亮逻辑优化问询
课程高亮逻辑优化方案
核心问题分析
原逻辑中isTimeBeforeEntry函数移除&& isCurrentTimeInEntry(...)后会高亮所有晚于当前时间的课程,本质是没有筛选出最近的那一个下节课,而是把所有符合时间条件的都标记了。
方案一:提前计算最近的下节课
直接先从课程列表里筛选出当日未开始的课程,排序后取第一个,只给这个课程加高亮,逻辑清晰且高效。
示例代码
// 定义工具函数:查找当日最近的下一节课 Pair? findNextUpcomingPair(List<Pair> pairs) { final now = DateTime.now(); // 筛选出今天内、开始时间晚于当前时间的课程 final upcoming = pairs.where((pair) { return pair.startTime.day == now.day && pair.startTime.isAfter(now); }).toList(); // 按开始时间从早到晚排序 upcoming.sort((a, b) => a.startTime.compareTo(b.startTime)); // 返回第一个(最近的),无符合条件的则返回null return upcoming.isNotEmpty ? upcoming.first : null; } // 在UI渲染前调用获取目标课程 final nextPair = findNextUpcomingPair(yourPairList); // 课程项渲染逻辑 Widget buildPairItem(Pair pair) { final isCurrent = isCurrentTimeInEntry(pair); final isNext = pair == nextPair; return Container( // 根据状态设置高亮背景色 color: isCurrent ? Colors.lightGreenAccent : isNext ? Colors.yellowAccent : null, child: // 课程内容组件 ); }
方案二:遍历标记法(外部变量控制)
如果不想提前计算,也可以在遍历课程列表时用一个外部变量标记是否已经找到下节课,找到后就不再给后续课程加高亮。
示例代码
// 遍历渲染课程列表时使用 List<Widget> buildPairList(List<Pair> pairs) { final now = DateTime.now(); bool hasMarkedNext = false; // 外部标记:是否已找到下节课 return pairs.map((pair) { final isCurrent = isCurrentTimeInEntry(pair); bool isNext = false; // 未标记过下节课、当前不是正在上的课、且课程在今天未开始 if (!hasMarkedNext && !isCurrent && pair.startTime.day == now.day && pair.startTime.isAfter(now)) { isNext = true; hasMarkedNext = true; // 标记已找到,后续课程不再触发 } return Container( color: isCurrent ? Colors.lightGreenAccent : isNext ? Colors.yellowAccent : null, child: // 课程内容组件 ); }).toList(); }
原函数逻辑修正(可选)
如果想保留isTimeBeforeEntry的结构,可修改为仅匹配最近的下一节课:
// 先获取当前时间和当前课程 final now = DateTime.now(); final currentPair = pairs.firstWhereOrNull(isCurrentTimeInEntry); Pair? nextPair; if (currentPair != null) { // 有当前课程时,找当前课程之后的第一个未开始课程 final currentIdx = pairs.indexOf(currentPair); if (currentIdx < pairs.length - 1) { nextPair = pairs.sublist(currentIdx + 1).firstWhereOrNull((p) { return p.startTime.day == now.day && p.startTime.isAfter(now); }); } } else { // 无当前课程时,找所有未开始课程中最早的 final upcoming = pairs.where((p) => p.startTime.day == now.day && p.startTime.isAfter(now)).toList(); upcoming.sort((a, b) => a.startTime.compareTo(b.startTime)); nextPair = upcoming.isNotEmpty ? upcoming.first : null; } // 后续渲染时用nextPair判断即可
内容的提问来源于stack exchange,提问作者Onovane
相关产品推荐
相关产品推荐

