import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/app_settings/app_colors.dart'; import 'package:star_lock/main/lockDetail/doorLockLog/date_time_extensions.dart'; class WeekCalendarView extends StatefulWidget { // 用于判断某一天是否有数据(激活状态) final bool Function(DateTime date)? hasData; final void Function(DateTime date)? onDateSelected; // 新增:选中日期回调 final void Function(DateTime start, DateTime end)? onWeekChanged; const WeekCalendarView({ Key? key, this.hasData, this.onDateSelected, this.onWeekChanged, }) : super(key: key); @override _WeekCalendarViewState createState() => _WeekCalendarViewState(); } class _WeekCalendarViewState extends State { final PageController _pageController = PageController(initialPage: 500); int _currentPage = 500; // 当前选中的日期(以 DateTime 格式存储) late DateTime _selectedDate; @override void initState() { super.initState(); _selectedDate = DateTime.now().withoutTime; // 默认选中今天 } // 获取指定 page 对应的一周日期 List _getWeekDatesForPage(int page) { final now = DateTime.now(); final baseSunday = DateTime(now.year, now.month, now.day - (now.weekday % 7)); final daysOffset = (page - 500) * 7; final targetSunday = baseSunday.add(Duration(days: daysOffset)); return List.generate( 7, (i) => DateTime( targetSunday.year, targetSunday.month, targetSunday.day + i)); } // 判断是否为今天 bool _isToday(DateTime date) { final now = DateTime.now(); return date.year == now.year && date.month == now.month && date.day == now.day; } // 判断是否为选中日期 bool _isSelected(DateTime date) { return date.year == _selectedDate.year && date.month == _selectedDate.month && date.day == _selectedDate.day; } // 判断是否有数据(激活状态) bool _hasData(DateTime date) { return widget.hasData?.call(date.withoutTime) ?? false; } void _onDateSelected(DateTime date) { setState(() { _selectedDate = date.withoutTime; }); // 触发回调,通知父组件 widget.onDateSelected?.call(date); } @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 当前周范围提示 _buildWeekRangeLabel(_currentPage), SizedBox(height: 10.h), SizedBox( height: 100.h, child: PageView.builder( controller: _pageController, itemCount: 1000, itemBuilder: (context, page) { final weekDates = _getWeekDatesForPage(page); return Row( children: weekDates.asMap().entries.map((entry) { final int index = entry.key; final DateTime date = entry.value; final bool isSelected = _isSelected(date); final bool hasData = _hasData(date); final bool isToday = _isToday(date); // 确定文字颜色 Color textColor; if (isSelected) { textColor = Colors.white; // 选中时文字为白色 } else if (hasData) { textColor = Colors.black; // 有数据:黑色 } else if (isToday) { textColor = Colors.black; // 今天:黑色 } else { textColor = Colors.grey; // 默认:灰色 } // 确定背景颜色 Color? bgColor; if (isSelected) { bgColor = AppColors.mainColor; // 选中用主题色 } // 其他状态无背景 return GestureDetector( onTap: () => _onDateSelected(date), child: Container( padding: EdgeInsets.all(4.w), width: 75.w, height: 75.w, decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(50.r), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( [ '简写周日', '简写周一', '简写周二', '简写周三', '简写周四', '简写周五', '简写周六' ][index] .tr, style: TextStyle( fontSize: 14.sp, color: textColor, fontWeight: FontWeight.w400, ), ), Text( date.day.toString(), style: TextStyle( fontSize: 26.sp, color: textColor, fontWeight: FontWeight.w600, ), ), if (isToday && !isSelected) // 今天但未选中 SizedBox(height: 2.h), if (isToday && !isSelected) Container( width: 6.w, height: 6.w, decoration: BoxDecoration( color: AppColors.mainColor, shape: BoxShape.circle, ), ), ], ), ), ); }).toList(), ); }, onPageChanged: (page) { setState(() { _currentPage = page; }); // ✅ 获取当前页对应的周的起止日期 final dates = _getWeekDatesForPage(page); final startOfWeek = dates.first; final endOfWeek = dates.last; // ✅ 触发回调,可用于请求接口 widget.onWeekChanged?.call(startOfWeek, endOfWeek); }, ), ), ], ); } Widget _buildWeekRangeLabel(int page) { final dates = _getWeekDatesForPage(page); final start = dates[0]; final end = dates[6]; String label; if (start.year == end.year) { // 同一年:显示为 "2025年8月18日 - 8月24日" label = '${start.year}${'年'.tr}${start.month}${'月'.tr}${start.day}${'日'.tr} - ${end.month}${'月'.tr}${end.day}${'日'.tr}'; } else { // 跨年:显示为 "2024年12月31日 - 2025年1月6日" label = '${start.year}${'年'.tr}${start.month}${'月'.tr}${start.day}${'日'.tr} - ${end.year}${'年'.tr}${end.month}${'月'.tr}${end.day}${'日'.tr}'; } return Text( label, style: TextStyle(fontSize: 24.sp, fontWeight: FontWeight.w600), ); } }