weekly_calendar.dart 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import 'package:flutter/material.dart';
  2. import 'package:intl/date_symbol_data_local.dart';
  3. import 'package:shared/utils/log_utils.dart';
  4. import 'calendar_utils.dart';
  5. import 'day_of_week_view.dart';
  6. import 'day_table_view.dart';
  7. /// 总入口,整合顶部的Week控件与底部的Days的PageView控件
  8. class WeeklyCalendar extends StatefulWidget {
  9. const WeeklyCalendar({
  10. super.key,
  11. this.onChangedSelectedDate,
  12. required this.maxDate,
  13. this.selectedDate,
  14. });
  15. final DateTime? selectedDate; //当前选中的日期
  16. final DateTime maxDate; //可选的最大日期
  17. final Function(DateTime)? onChangedSelectedDate; //选择日期的回调
  18. @override
  19. State<StatefulWidget> createState() => _WeeklyCalendarState();
  20. }
  21. class _WeeklyCalendarState extends State<WeeklyCalendar> {
  22. final DateTime now = DateTime.now();
  23. DateTime? selectedDate;
  24. late List<DateTime> currentDateList;
  25. @override
  26. void initState() {
  27. initializeDateFormatting("en"); //日期国际化指定
  28. super.initState();
  29. currentDateList = get2Weekdays(now, 0); //双周的数据
  30. selectedDate = widget.selectedDate ?? now; //默认选中的数据
  31. }
  32. @override
  33. void didUpdateWidget(covariant WeeklyCalendar oldWidget) {
  34. super.didUpdateWidget(oldWidget);
  35. if (widget.selectedDate != oldWidget.selectedDate) {
  36. //查看当前页面Date数据是否包含选中的 selectedDate
  37. bool hasSelected = hasSelectedDate(currentDateList, widget.selectedDate ?? now);
  38. setState(() {
  39. selectedDate = widget.selectedDate;
  40. if (!hasSelected) {
  41. //如果不包含,需要更换数据源
  42. Log.d("选中日期不在当前页面,需要更换数据源");
  43. currentDateList = get2Weekdays(widget.selectedDate ?? now, 0);
  44. }
  45. });
  46. }
  47. }
  48. @override
  49. Widget build(BuildContext context) {
  50. return Column(
  51. mainAxisSize: MainAxisSize.min,
  52. children: [
  53. //顶部是固定的星期布局
  54. customDayOfWeek(),
  55. const SizedBox(height: 12),
  56. //底部是当前二周的数据
  57. DayTableView(
  58. weekdays: currentDateList,
  59. onSelect: (date) {
  60. setState(() {
  61. selectedDate = date;
  62. });
  63. //主动点击之后回调
  64. widget.onChangedSelectedDate?.call(date);
  65. },
  66. selectedDate: selectedDate ?? now,
  67. maxDate: widget.maxDate,
  68. currentDate: now,
  69. )
  70. ],
  71. );
  72. }
  73. //星期的文本显示
  74. Widget customDayOfWeek() {
  75. final weekdays = getWeekdays(now, 0);
  76. return DayOfWeekView(weekdays: weekdays);
  77. }
  78. }