Przeglądaj źródła

组件间数据互通

gavin.chen 2 lat temu
rodzic
commit
12c863b928

+ 132 - 40
lib/calendar_controller/controller.dart

@@ -1,17 +1,44 @@
+import 'dart:math';
+
 import 'package:calendar_view/utils/calendar_util.dart';
 import 'package:calendar_view/utils/event_type.dart';
+import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 
 class CalendarController extends GetxController {
   CalendarController();
 
+  /// 虚拟的日程数据
+  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),
+  ];
+
   /// 数据项:当前年份,当前月份,当前日期
   int currentYear = 2022; // 当前年份
   int currentMonth = 12; // 当前月份
   int selectedDayIndex = 0; // 当前选择的日期的下标,从0开始,范围是0-34 有时是 0-41
   int maxDaysLength = 35; // 最大的日期数组长度,有时是42
-  List<Schedule> scheduleList = []; // 当前维护的日程列表
+  List<Schedule> scheduleList = []; // 当前维护的日程列表【数据源】
   List<ScheduleType> scheduleTypeList = []; // 当前维护的一个日程类型列表
+  List<String> needDisplayTypeNameList = []; // 维护一个需要展示的日程类型列表
   List<MiniViewDayStructure> miniViewDaysList = []; // 当前维护的迷你日历列表
   /// 日程列表与日期列表拼装,即可变成月视图大列表,将日程塞入每一天
   List<MonthViewDayStructure> get monthViewDaysList {
@@ -30,13 +57,13 @@ class CalendarController extends GetxController {
     }
     for (final Schedule schedule in scheduleList) {
       final DateTime scheduleDate = schedule.day;
-      final int scheduleDay = scheduleDate.day;
+      // final int scheduleDay = scheduleDate.day;
       for (int i = 0; i < maxDaysLength; i++) {
         final MiniViewDayStructure miniViewDayStructure = miniViewDaysList[i];
         final MonthViewDayStructure monthViewDayStructure =
             monthViewDaysList[i];
         if (miniViewDayStructure.isCurrentMonth &&
-            miniViewDayStructure.date.day == scheduleDay) {
+            miniViewDayStructure.date == scheduleDate) {
           monthViewDayStructure.scheduleList.add(schedule);
         }
       }
@@ -44,7 +71,7 @@ class CalendarController extends GetxController {
     return monthViewDaysList;
   }
 
-  /// TODO[Gavin]: i18n
+  /// TODO:[Gavin] i18n
   String get currentYearMonth => '$currentYear$currentMonth月';
   bool get isToday => miniViewDaysList[selectedDayIndex].isToday;
   int get calendarLines => maxDaysLength ~/ 7;
@@ -62,43 +89,77 @@ class CalendarController extends GetxController {
     currentMonth = now.month;
     miniViewDaysList = _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),
-    ];
-
     _initMockScheduleType();
     _initMockSchedule(mockSchedule);
-    _setSchedule(mockSchedule);
-    print("CalendarController 全局临时控制器初始化");
+    // 设置mini日历的日程下标
+    updateScheduleTypeList();
+    _setMiniCalendarSchedule();
+    // print("CalendarController 全局临时控制器初始化");
   }
 
+  /// TODO:[Gavin] 改为真实数据接口
+  /// 创建日程类型,填充到scheduleTypeList
   void _initMockScheduleType() {
-    /// 创建5个假日程类型,填充到scheduleTypeList
+    scheduleTypeList = [
+      ScheduleType(
+        typeName: '我的日程',
+        color: Colors.red,
+        isSelected: true,
+      ),
+      ScheduleType(
+        typeName: '工作日程',
+        color: Colors.blue,
+        isSelected: true,
+      ),
+      ScheduleType(
+        typeName: '会议日程',
+        color: Colors.green,
+        isSelected: true,
+      ),
+      ScheduleType(
+        typeName: '其他日程',
+        color: Colors.orange,
+        isSelected: true,
+      ),
+    ];
+  }
+
+  /// 更新日程列表显示情况【只接收状态更新,不修改 scheduleTypeList】
+  void updateScheduleTypeList() {
+    // 更新 needDisplayTypeNameList
+    needDisplayTypeNameList = [];
+    for (var element in scheduleTypeList) {
+      if (element.isSelected) {
+        needDisplayTypeNameList.add(element.typeName);
+      }
+    }
+    _setMiniCalendarSchedule();
+    // 通知更新
+    onDaysListChange.emit(this, null);
   }
 
   /// TODO:[Gavin] 改为真实数据接口
-  void _initMockSchedule(List<DateTime> scheduleList) {
-    /// 创建30个假日程数据,填充到scheduleList
+  void _initMockSchedule(List<DateTime> mockSchedule) {
+    // 遍历mockSchedule的每一天,向 scheduleList 中添加日程,每天添加3个日程
+    for (final DateTime date in mockSchedule) {
+      int num = _getRandomInt(0, 10);
+      for (int i = 0; i < num; i++) {
+        int typeIndex = _getRandomInt(0, scheduleTypeList.length);
+        final Schedule schedule = Schedule(
+          day: date,
+          type: scheduleTypeList[typeIndex],
+          title: '${scheduleTypeList[typeIndex].typeName} - Mock标题',
+          content: '日程内容',
+        );
+        scheduleList.add(schedule);
+      }
+    }
+  }
+
+  /// 取随机整数
+  int _getRandomInt(int min, int max) {
+    final Random random = Random();
+    return min + random.nextInt(max - min);
   }
 
   /// 传入起始年月,返回35个日期结构体
@@ -201,6 +262,7 @@ class CalendarController extends GetxController {
       currentYear = now.year;
       currentMonth = now.month;
       miniViewDaysList = _countDaysList(currentYear, currentMonth);
+      _setMiniCalendarSchedule();
     }
     for (var element in miniViewDaysList) {
       if (element.isToday) {
@@ -211,14 +273,22 @@ class CalendarController extends GetxController {
   }
 
   /// 给日期设置日程的值
-  void _setSchedule(List<DateTime> scheduleList) {
-    /// 如果scheduleList中存在daysList中的日期,则设置hasSchedule为true
-    for (var element in scheduleList) {
-      for (var day in miniViewDaysList) {
-        if (element.year == day.date.year &&
-            element.month == day.date.month &&
-            element.day == day.date.day) {
+  void _setMiniCalendarSchedule() {
+    /// 如果 scheduleList 中存在 daysList 中的日期,则设置 hasSchedule 为 true
+    for (var day in miniViewDaysList) {
+      day.hasSchedule = false;
+      for (var element in scheduleList) {
+        var existSchedule = false;
+        if (element.day.year == day.date.year &&
+            element.day.month == day.date.month &&
+            element.day.day == day.date.day) {
+          if (_isDisplayScheduleType(element.type.typeName)) {
+            existSchedule = true;
+          }
+        }
+        if (existSchedule) {
           day.hasSchedule = true;
+          break;
         }
       }
     }
@@ -233,6 +303,8 @@ class CalendarController extends GetxController {
       currentMonth--;
     }
     miniViewDaysList = _countDaysList(currentYear, currentMonth);
+    _setMiniCalendarSchedule();
+
     _selectFirstDay();
 
     onDaysListChange.emit(this, null);
@@ -247,8 +319,28 @@ class CalendarController extends GetxController {
       currentMonth++;
     }
     miniViewDaysList = _countDaysList(currentYear, currentMonth);
+    _setMiniCalendarSchedule();
     _selectFirstDay();
 
     onDaysListChange.emit(this, null);
   }
+
+  /// 日程数据筛选器【仅筛选出需要显示的日程】
+  List<Schedule> scheduleListFilter(List<Schedule> scheduleList) {
+    final List<Schedule> result = [];
+    for (Schedule element in scheduleList) {
+      if (_isDisplayScheduleType(element.type.typeName)) {
+        result.add(element);
+      }
+    }
+    return result;
+  }
+
+  /// 是否为需要显示的日程
+  bool _isDisplayScheduleType(String typeName) {
+    if (needDisplayTypeNameList.contains(typeName)) {
+      return true;
+    }
+    return false;
+  }
 }

+ 12 - 2
lib/calendar_view/calendar_left_panel.dart

@@ -96,7 +96,12 @@ class _CalendarLeftPanelState extends State<CalendarLeftPanel> {
                       MaterialStateProperty.all<Color>(Colors.transparent),
                 ),
                 onPressed: (() {
-                  // TODO
+                  ScaffoldMessenger.of(context).showSnackBar(
+                    const SnackBar(
+                      duration: Duration(milliseconds: 500),
+                      content: Text('前方正在施工'),
+                    ),
+                  );
                 }),
                 child: const Icon(Icons.add),
               ),
@@ -154,7 +159,12 @@ class _CalendarLeftPanelState extends State<CalendarLeftPanel> {
                   style: TextStyle(color: Colors.black87),
                 ),
                 onPressed: () {
-                  //TODO
+                  ScaffoldMessenger.of(context).showSnackBar(
+                    const SnackBar(
+                      duration: Duration(milliseconds: 500),
+                      content: Text('前方正在施工'),
+                    ),
+                  );
                 },
               ),
             ),

+ 6 - 1
lib/calendar_view/month_calendar/month_calendar_item.dart

@@ -1,7 +1,9 @@
+import 'package:calendar_view/calendar_controller/controller.dart';
 import 'package:calendar_view/utils/calendar_util.dart';
 import 'package:calendar_view/utils/chinese_calendar_utils.dart';
 import 'package:calendar_view/calendar_view/month_calendar/schedule_list.dart';
 import 'package:flutter/material.dart';
+import 'package:get/get.dart';
 
 /// 月历的每一格日期
 class MonthDayItem extends StatefulWidget {
@@ -22,6 +24,8 @@ class MonthDayItem extends StatefulWidget {
 class _MyWidgetState extends State<MonthDayItem> {
   late MonthViewDayStructure _dayData;
   late BoxDecoration _dateContainerDecoration;
+  CalendarController calendarController = Get.find<CalendarController>();
+
   BoxDecoration _gridContainerDecoration = const BoxDecoration(
     color: Colors.white,
   );
@@ -144,7 +148,8 @@ class _MyWidgetState extends State<MonthDayItem> {
         width: double.infinity,
         child: ScheduleList(
           maxLines: widget.maxScheduleLines,
-          scheduleDataList: widget.dayData.scheduleList,
+          scheduleDataList: calendarController
+              .scheduleListFilter(widget.dayData.scheduleList),
         ),
       ),
     );

+ 10 - 6
lib/calendar_view/month_calendar/schedule_list.dart

@@ -72,6 +72,7 @@ class ScheduleListState extends State<ScheduleList> {
       }
     }
     ScheduleType scheduleType = widget.scheduleDataList[scheduleIndex].type;
+    Schedule schedule = widget.scheduleDataList[scheduleIndex];
     return Material(
       color: Colors.transparent,
       child: InkWell(
@@ -84,9 +85,9 @@ class ScheduleListState extends State<ScheduleList> {
           height: widget.itemHeight,
           padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 0),
           decoration: BoxDecoration(
-            color: scheduleType.isSelected
-                ? scheduleType.color.withOpacity(0.2)
-                : Colors.transparent,
+            // color: scheduleType.isSelected
+            //     ? scheduleType.color.withOpacity(0.2)
+            //     : Colors.transparent,
             borderRadius: BorderRadius.circular(5),
           ),
           child: Row(
@@ -100,9 +101,12 @@ class ScheduleListState extends State<ScheduleList> {
                 ),
               ),
               const SizedBox(width: 10),
-              Text(
-                scheduleType.typeName,
-                style: const TextStyle(fontSize: 12),
+              Expanded(
+                child: Text(
+                  schedule.title,
+                  style: const TextStyle(fontSize: 12),
+                  overflow: TextOverflow.ellipsis,
+                ),
               ),
             ],
           ),

+ 28 - 8
lib/calendar_view/my_calendar/my_calendar.dart

@@ -1,6 +1,8 @@
+import 'package:calendar_view/calendar_controller/controller.dart';
 import 'package:calendar_view/utils/calendar_util.dart';
 import 'package:calendar_view/calendar_view/my_calendar/my_schedule_item.dart';
 import 'package:flutter/material.dart';
+import 'package:get/get.dart';
 
 /// 我的日历模块,是个ListView,可以展开收起
 class MyCalendar extends StatefulWidget {
@@ -13,12 +15,27 @@ class MyCalendar extends StatefulWidget {
 class _MyCalendarState extends State<MyCalendar> {
   bool _isExpanded = true;
   bool _isTitleHover = false;
-  List<ScheduleType> mockScheduleTypeList = [
-    ScheduleType(typeName: '我的日程', isSelected: true, color: Colors.red),
-    ScheduleType(typeName: '你的日程', isSelected: true, color: Colors.blue),
-    ScheduleType(typeName: '他的日程', isSelected: true, color: Colors.green),
-    ScheduleType(typeName: '她的日程', isSelected: true, color: Colors.pink),
-  ];
+  List<ScheduleType> _scheduleTypeList = [];
+  CalendarController calendarController = Get.find<CalendarController>();
+
+  @override
+  void initState() {
+    super.initState();
+    _scheduleTypeList = calendarController.scheduleTypeList;
+    calendarController.onDaysListChange.addListener(_onDaysListChange);
+  }
+
+  @override
+  void dispose() {
+    super.dispose();
+    calendarController.onDaysListChange.removeListener(_onDaysListChange);
+  }
+
+  void _onDaysListChange(_, e) {
+    setState(() {
+      _scheduleTypeList = calendarController.scheduleTypeList;
+    });
+  }
 
   @override
   Widget build(BuildContext context) {
@@ -27,7 +44,7 @@ class _MyCalendarState extends State<MyCalendar> {
         shrinkWrap: true,
         children: <Widget>[
           _buildMyCalendarTitle(),
-          if (_isExpanded) ...mockScheduleTypeList.map(_buildMyCalendarItem),
+          if (_isExpanded) ..._scheduleTypeList.map(_buildMyCalendarItem),
         ],
       ),
     );
@@ -89,7 +106,10 @@ class _MyCalendarState extends State<MyCalendar> {
   }
 
   Widget _buildMyCalendarItem(ScheduleType type) {
-    return MyScheduleItem(type: type);
+    return MyScheduleItem(
+      type: type,
+      onClick: () => calendarController.updateScheduleTypeList(),
+    );
   }
 
   void _handleMouseEnter(PointerEvent details) {

+ 5 - 14
lib/calendar_view/my_calendar/my_schedule_item.dart

@@ -2,28 +2,17 @@ import 'package:calendar_view/utils/calendar_util.dart';
 import 'package:flutter/material.dart';
 
 class MyScheduleItem extends StatefulWidget {
-  const MyScheduleItem({super.key, required this.type});
+  const MyScheduleItem({super.key, required this.type, required this.onClick});
   final ScheduleType type;
+  final VoidCallback onClick;
 
   @override
   State<MyScheduleItem> createState() => _MyScheduleItemState();
 }
 
 class _MyScheduleItemState extends State<MyScheduleItem> {
-  late ScheduleType _type;
   bool _isHover = false;
-
-  @override
-  void initState() {
-    super.initState();
-    _type = widget.type;
-  }
-
-  @override
-  void didUpdateWidget(MyScheduleItem oldWidget) {
-    super.didUpdateWidget(oldWidget);
-    _type = widget.type;
-  }
+  get _type => widget.type;
 
   @override
   Widget build(BuildContext context) {
@@ -36,6 +25,7 @@ class _MyScheduleItemState extends State<MyScheduleItem> {
           setState(() {
             _type.isSelected = !_type.isSelected;
           });
+          widget.onClick.call();
         },
         child: Container(
           height: 40,
@@ -60,6 +50,7 @@ class _MyScheduleItemState extends State<MyScheduleItem> {
                         _type.isSelected = v!;
                       },
                     );
+                    widget.onClick.call();
                   },
                 ),
               ),