123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- import 'package:calendar_view/utils/calendar_util.dart';
- import 'package:calendar_view/utils/event_type.dart';
- import 'package:get/get.dart';
- class CalendarController extends GetxController {
- CalendarController();
- /// 数据项:当前年份,当前月份,当前日期
- int currentYear = 2022; // 当前年份
- int currentMonth = 12; // 当前月份
- int selectedDayIndex = 0; // 当前选择的日期的下标,从0开始,范围是0-34 有时是 0-41
- int maxDaysLength = 35; // 最大的日期数组长度,有时是42
- List<DayStructure> daysList = []; // 当前维护的日期列表
- ///TODO: 维护一个日程列表
- /// TODO[Gavin]: i18n
- String get currentYearMonth => '$currentYear年$currentMonth月';
- bool get isToday => daysList[selectedDayIndex].isToday;
- int get calendarLines => maxDaysLength ~/ 7;
- // _initData() {
- // update(["calendar"]);
- // }
- FEventHandler<void> onDaysListChange = FEventHandler<void>();
- void onTap() {}
- @override
- void onInit() {
- super.onInit();
- /// 获取当前时间判断年月
- final DateTime now = DateTime.now();
- currentYear = now.year;
- currentMonth = now.month;
- daysList = _countDaysList(currentYear, currentMonth);
- selectToday();
- /// 虚拟的日程数据
- final List<DateTime> mockSchedule = [
- DateTime(2022, 12, 1),
- DateTime(2022, 12, 4),
- DateTime(2022, 12, 5),
- DateTime(2022, 12, 6),
- DateTime(2022, 12, 7),
- DateTime(2022, 12, 12),
- DateTime(2022, 12, 13),
- DateTime(2022, 12, 14),
- DateTime(2022, 12, 15),
- DateTime(2022, 12, 16),
- DateTime(2022, 12, 17),
- DateTime(2022, 12, 18),
- DateTime(2022, 12, 19),
- DateTime(2022, 12, 20),
- DateTime(2022, 12, 27),
- DateTime(2022, 12, 28),
- DateTime(2022, 12, 29),
- DateTime(2022, 12, 30),
- DateTime(2022, 12, 31),
- ];
- _setSchedule(mockSchedule);
- print("CalendarController 全局临时控制器初始化");
- }
- @override
- void onReady() {
- super.onReady();
- // _initData();
- }
- // @override
- // void onClose() {
- // super.onClose();
- // }
- /// 传入起始年月,返回35个日期结构体
- List<DayStructure> _countDaysList(int year, int month) {
- maxDaysLength = _isNeedExtraRow(year, month) ? 42 : 35;
- final daysList = <DayStructure>[];
- final firstDay = DateTime(year, month, 1);
- final firstDayWeek = firstDay.weekday;
- final lastDay = DateTime(year, month + 1, 0);
- final lastDayOfMonth = lastDay.day;
- final lastDayOfLastMonth = DateTime(year, month, 0).day;
- final today = DateTime.now();
- /// 转换后的 firstDayWeek
- final firstDayWeekIndex = (firstDayWeek) % 7;
- int nextMonthDay = 1;
- // 上个月的日期
- for (var i = 0; i < firstDayWeekIndex; i++) {
- daysList.add(
- DayStructure(
- index: i,
- date: DateTime(
- year, month - 1, lastDayOfLastMonth - firstDayWeekIndex + i + 1),
- isCurrentMonth: false,
- ),
- );
- }
- // 当月的日期
- for (var i = 0;
- (i < lastDayOfMonth) && daysList.length < maxDaysLength;
- i++) {
- daysList.add(
- DayStructure(
- index: i + firstDayWeek,
- date: DateTime(year, month, i + 1),
- isToday:
- today.year == year && today.month == month && today.day == i + 1,
- ),
- );
- }
- while (daysList.length < maxDaysLength) {
- daysList.add(DayStructure(
- index: daysList.length,
- date: DateTime(month == 12 ? year + 1 : year,
- month == 12 ? 1 : month + 1, nextMonthDay),
- isCurrentMonth: false,
- ));
- nextMonthDay++;
- }
- return daysList;
- }
- /// 计算是否需要显示六行日期,一般为5行,但是有时候会有6行
- bool _isNeedExtraRow(int year, int month) {
- final firstDay = DateTime(year, month, 1);
- final firstDayWeek = firstDay.weekday;
- final lastDay = DateTime(year, month + 1, 0);
- final lastDayOfMonth = lastDay.day;
- /// 转换后的firstDayWeek,%7是因为DateTime的weekday是从周日开始的,而我们的日历是从周一开始的
- final firstDayWeekIndex = (firstDayWeek) % 7;
- return firstDayWeekIndex + lastDayOfMonth > 35;
- }
- /// 通过下标选中日期,下标从0开始,允许的范围是0-34,有时是 0-42
- void handleSelectedDayByIndex(int index) {
- assert(index >= 0 && index < maxDaysLength,
- 'index must be in 0-$maxDaysLength');
- assert(daysList.length == maxDaysLength,
- 'daysList length must be maxDaysLength');
- for (var element in daysList) {
- if (element.index == index) {
- element.isSelected = true;
- } else {
- element.isSelected = false;
- }
- }
- selectedDayIndex = index;
- onDaysListChange.emit(this, null);
- }
- /// 选中当月第一天
- void _selectFirstDay() {
- for (var element in daysList) {
- if (element.isCurrentMonth) {
- handleSelectedDayByIndex(element.index);
- break;
- }
- }
- }
- /// 选中今天
- void selectToday() {
- /// 如果当前不是当月,则切换到当月
- final DateTime now = DateTime.now();
- if (currentYear != now.year || currentMonth != now.month) {
- currentYear = now.year;
- currentMonth = now.month;
- daysList = _countDaysList(currentYear, currentMonth);
- }
- for (var element in daysList) {
- if (element.isToday) {
- handleSelectedDayByIndex(element.index);
- break;
- }
- }
- }
- /// 给日期设置日程的值
- void _setSchedule(List<DateTime> scheduleList) {
- /// 如果scheduleList中存在daysList中的日期,则设置hasSchedule为true
- for (var element in scheduleList) {
- for (var day in daysList) {
- if (element.year == day.date.year &&
- element.month == day.date.month &&
- element.day == day.date.day) {
- day.hasSchedule = true;
- }
- }
- }
- }
- /// 上个月
- void handleLastMonth() {
- if (currentMonth == 1) {
- currentMonth = 12;
- currentYear--;
- } else {
- currentMonth--;
- }
- daysList = _countDaysList(currentYear, currentMonth);
- _selectFirstDay();
- onDaysListChange.emit(this, null);
- }
- /// 下个月
- void handleNextMonth() {
- if (currentMonth == 12) {
- currentMonth = 1;
- currentYear++;
- } else {
- currentMonth++;
- }
- daysList = _countDaysList(currentYear, currentMonth);
- _selectFirstDay();
- onDaysListChange.emit(this, null);
- }
- }
|