TableCalendar状态更新异常:日期标记切换月份后消失求助
问题解决:TableCalendar切换月份后锻炼日期标记消失
核心问题
你仅实现了defaultBuilder,但TableCalendar中的日期存在多种状态:
default:当前显示月份内的非选中、非今日日期outside:当前显示月份外的日期(切换月份后,上月/下月的日期会进入该状态)selected:用户选中的日期
未处理outsideBuilder会导致切换月份后,非当前月的锻炼日期丢失标记;未处理selectedBuilder则会让选中的锻炼日期无法正常显示标记。同时需确认worked_out_days中的日期时区与日历使用的时区一致,避免isSameDay判断失效。
修复后的代码
修改calendarBuilders部分,补充outsideBuilder和selectedBuilder,并提取判断逻辑复用:
calendarBuilders: CalendarBuilders( // 处理当前月非选中日期 defaultBuilder: _buildWorkoutDayMarker, // 处理非当前月日期 outsideBuilder: _buildWorkoutDayMarker, // 处理选中日期 selectedBuilder: (context, day, focusedDay) { bool workedOut = worked_out_days.any( (workedOutDay) => isSameDay(workedOutDay, day) ); return Container( margin: const EdgeInsets.all(4.0), decoration: BoxDecoration( color: AppColors(theme).darkGreen, shape: BoxShape.circle, // 若为锻炼日期,可叠加外层圈(可选) ...(workedOut ? [ BoxDecoration(border: Border.all(color: AppColors(theme).footerGrey, width: 2)) ] : []) ), child: Center( child: Text( '${day.day}', style: TextStyle(color: AppColors(theme).primaryText), ), ), ); }, ),
提取复用的标记构建方法:
Widget? _buildWorkoutDayMarker(BuildContext context, DateTime day, DateTime focusedDay) { bool workedOut = worked_out_days.any( (workedOutDay) => isSameDay(workedOutDay, day) ); return workedOut ? Container( margin: const EdgeInsets.all(4.0), decoration: BoxDecoration( color: AppColors(theme).footerGrey, shape: BoxShape.circle, ), child: Center( child: Text( '${day.day}', style: TextStyle(color: AppColors(theme).primaryText), ), ), ) : null; }
额外检查项
- 统一时区:你设置的
firstDay/lastDay是UTC时间,但focusedDay默认是本地时间,可能导致isSameDay判断出错。可将firstDay/lastDay改为本地时间:firstDay: DateTime(1900, 10, 16), lastDay: DateTime(2200, 3, 14),
内容的提问来源于stack exchange,提问作者Cidiko Andorem
相关产品推荐
相关产品推荐

