123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- import 'dart:html';
- import 'package:calendar_view/calendar_controller/controller.dart';
- import 'package:calendar_view/utils/calendar_util.dart';
- import 'package:calendar_view/calendar_page/month_calendar/month_calendar_item.dart';
- import 'package:flutter/foundation.dart';
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
- class MonthCalendar extends StatefulWidget {
- const MonthCalendar({super.key});
- @override
- State<MonthCalendar> createState() => _MonthCalendarState();
- }
- class _MonthCalendarState extends State<MonthCalendar> {
- List<MonthViewDayStructure> monthViewDaysList = []; // 当前控制器的日期列表
- CalendarController calendarController = Get.find<CalendarController>();
- int _maxScheduleLines = 3; // 最大的日程行数【需要动态计算】
- double _viewHeight = 0; // 维护一个视口高度,如果视口高度不变,那么日程的高度不需要计算
- int _calendarLines = 0; // 维护一个日历行数,如果日历行数不变,那么日程的高度不需要计算
- @override
- void initState() {
- super.initState();
- /// 监控resize事件,动态计算最大日程行数
- WidgetsBinding.instance.addPostFrameCallback((_) {
- _handleMaxScheduleLines();
- });
- /// web端监听resize事件
- if (kIsWeb) {
- window.onResize.listen((event) {
- WidgetsBinding.instance.addPostFrameCallback((_) {
- _handleMaxScheduleLines();
- });
- });
- }
- monthViewDaysList = calendarController.monthViewDaysList;
- calendarController.onDaysListChange.addListener(_onDaysListChange);
- }
- @override
- void dispose() {
- super.dispose();
- calendarController.onDaysListChange.removeListener(_onDaysListChange);
- }
- void _onDaysListChange(_, e) {
- setState(() {
- monthViewDaysList = calendarController.monthViewDaysList;
- });
- _handleMaxScheduleLines();
- }
- @override
- Widget build(BuildContext context) {
- return Column(
- children: <Widget>[
- _buildMonthCalendarWeekTitle(),
- Expanded(child: _buildMonthCalendarDaysBody()),
- ],
- );
- }
- /// 构建「日、一、二、三、四、五、六」的标题
- Widget _buildMonthCalendarWeekTitle() {
- return SizedBox(
- height: 30,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- children: <Widget>[
- /// TODO[Gavin]: i18n
- _buildEachTitle('周日'),
- _buildEachTitle('周一'),
- _buildEachTitle('周二'),
- _buildEachTitle('周三'),
- _buildEachTitle('周四'),
- _buildEachTitle('周五'),
- _buildEachTitle('周六'),
- ],
- ),
- );
- }
- Widget _buildEachTitle(String title) {
- const weekTextStyle = TextStyle(fontSize: 12, color: Colors.black);
- return SizedBox(
- width: 25,
- child: Text(
- title,
- style: weekTextStyle,
- textAlign: TextAlign.center,
- ),
- );
- }
- /// 构建日历主体
- Widget _buildMonthCalendarDaysBody() {
- // 将35天分成5个周
- final weeksInMonth = <List<MonthViewDayStructure>>[];
- for (var i = 0; i < monthViewDaysList.length; i += 7) {
- weeksInMonth.add(monthViewDaysList.sublist(i, i + 7));
- }
- return SizedBox(
- child: Column(
- mainAxisSize: MainAxisSize.max,
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- children: weeksInMonth.map(_buildMonthCalendarDayRow).toList(),
- ),
- );
- }
- /// 构建每一行(周)
- Widget _buildMonthCalendarDayRow(List<MonthViewDayStructure> sevenDays) {
- return Expanded(
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- children: sevenDays.map(_buildEachDay).toList(),
- ),
- );
- }
- /// 构建每一天
- Widget _buildEachDay(MonthViewDayStructure day) {
- return Expanded(
- child: Container(
- decoration: const BoxDecoration(
- border: Border(
- right: BorderSide(
- color: Colors.black12,
- width: 1,
- ),
- top: BorderSide(
- color: Colors.black12,
- width: 1,
- ),
- ),
- ),
- child: MonthDayItem(
- dayData: day,
- maxScheduleLines: _maxScheduleLines,
- ),
- ),
- );
- }
- /// 动态计算日历格内的最大日程行数
- void _handleMaxScheduleLines() {
- final size = MediaQuery.of(context).size;
- if (size.height == _viewHeight &&
- calendarController.calendarLines == _calendarLines) return;
- _viewHeight = size.height;
- _calendarLines = calendarController.calendarLines;
- final gridRows = calendarController.calendarLines;
- final gridHeight = size.height - 100; // 100 是日历头部的高度
- final gridItemHeight = gridHeight / gridRows;
- final scheduleAreaHeight = gridItemHeight - 30; // 30 是日期的高度
- final maxLines = (scheduleAreaHeight / 20).floor();
- setState(() {
- _maxScheduleLines = maxLines;
- });
- }
- }
|