Browse Source

更新弹出层控制器

gavin.chen 2 years ago
parent
commit
591a17091f

+ 0 - 1
lib/calendar_controller/controller.dart

@@ -78,7 +78,6 @@ class CalendarController extends GetxController {
 
   /// 数据变更事件通知
   FEventHandler<void> onDaysListChange = FEventHandler<void>();
-
   @override
   void onInit() {
     super.onInit();

+ 9 - 1
lib/calendar_page/calendar_main_panel.dart

@@ -2,6 +2,8 @@ import 'package:calendar_view/calendar_controller/controller.dart';
 import 'package:calendar_view/calendar_page/calendar_views/calendar_month_view.dart';
 import 'package:calendar_view/calendar_page/mini_calendar/mini_calendar.dart';
 import 'package:calendar_view/calendar_page/my_calendar/my_calendar.dart';
+import 'package:calendar_view/popup_layer/popup_layer.dart';
+import 'package:calendar_view/popup_layer/popup_layer_controller.dart';
 import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 
@@ -24,6 +26,7 @@ class _CalendarMainPanelState extends State<CalendarMainPanel> {
   @override
   void initState() {
     super.initState();
+    Get.put<PopupLayerController>(PopupLayerController());
     _isToday = calendarController.isToday;
     _currYearMonthStr = calendarController.currentYearMonth;
     calendarController.onDaysListChange.addListener(_onDaysListChange);
@@ -70,7 +73,12 @@ class _CalendarMainPanelState extends State<CalendarMainPanel> {
         children: <Widget>[
           _buildMainPanelTop(),
           Expanded(
-            child: _buildMainView(_viewType),
+            child: Stack(
+              children: [
+                _buildMainView(_viewType),
+                const PopupLayer(),
+              ],
+            ),
           ),
         ],
       ),

+ 8 - 1
lib/calendar_page/month_calendar/month_calendar_item.dart

@@ -1,4 +1,5 @@
 import 'package:calendar_view/calendar_controller/controller.dart';
+import 'package:calendar_view/popup_layer/popup_layer_controller.dart';
 import 'package:calendar_view/utils/calendar_util.dart';
 import 'package:calendar_view/utils/chinese_calendar_utils.dart';
 import 'package:calendar_view/calendar_page/month_calendar/schedule_list.dart';
@@ -25,12 +26,13 @@ class _MyWidgetState extends State<MonthDayItem> {
   late MonthViewDayStructure _dayData;
   late BoxDecoration _dateContainerDecoration;
   CalendarController calendarController = Get.find<CalendarController>();
-
+  PopupLayerController popupLayerController = Get.find<PopupLayerController>();
   BoxDecoration _gridContainerDecoration = const BoxDecoration(
     color: Colors.white,
   );
   late TextStyle _dayTextStyle;
   late TextStyle _lunarDayTextStyle;
+  GlobalKey _monthGridKey = GlobalKey();
 
   /// TODO[Gavin]: i18n
   get displayStr => _dayData.isToday ? '今' : _dayData.date.day.toString();
@@ -109,6 +111,7 @@ class _MyWidgetState extends State<MonthDayItem> {
   @override
   Widget build(BuildContext context) {
     return Container(
+      key: _monthGridKey,
       decoration: _gridContainerDecoration,
       child: Column(
         children: [
@@ -150,6 +153,10 @@ class _MyWidgetState extends State<MonthDayItem> {
           maxLines: widget.maxScheduleLines,
           scheduleDataList: calendarController
               .scheduleListFilter(widget.dayData.scheduleList),
+          onTapShowMore: () {
+            popupLayerController.handlePopupMoreSchedule(
+                _monthGridKey, widget.dayData);
+          },
         ),
       ),
     );

+ 8 - 7
lib/calendar_page/month_calendar/schedule_list.dart

@@ -1,13 +1,16 @@
 import 'dart:math';
 
+import 'package:calendar_view/popup_layer/popup_layer_controller.dart';
 import 'package:calendar_view/utils/calendar_util.dart';
 import 'package:flutter/material.dart';
+import 'package:get/get.dart';
 
 class ScheduleList extends StatefulWidget {
   const ScheduleList({
     Key? key,
     required this.maxLines,
     required this.scheduleDataList,
+    required this.onTapShowMore,
   }) : super(key: key);
 
   /// 可容纳的最大日程行数
@@ -19,6 +22,9 @@ class ScheduleList extends StatefulWidget {
   /// 日程数据
   final List<Schedule> scheduleDataList;
 
+  /// 点击显示更多
+  final VoidCallback onTapShowMore;
+
   @override
   ScheduleListState createState() => ScheduleListState();
 }
@@ -26,6 +32,7 @@ class ScheduleList extends StatefulWidget {
 class ScheduleListState extends State<ScheduleList> {
   /// 容纳的数量
   int _itemCount = 0;
+  PopupLayerController popupLayerController = Get.find<PopupLayerController>();
 
   @override
   void initState() {
@@ -131,13 +138,7 @@ class ScheduleListState extends State<ScheduleList> {
           borderRadius: BorderRadius.circular(5),
         ),
         onTap: () {
-          /// 弹出提示
-          ScaffoldMessenger.of(context).showSnackBar(
-            const SnackBar(
-              duration: Duration(milliseconds: 500),
-              content: Text('前方正在施工'),
-            ),
-          );
+          widget.onTapShowMore.call();
         },
         hoverColor: const Color.fromARGB(255, 227, 228, 228),
         child: Container(

+ 108 - 0
lib/popup_layer/popup_layer.dart

@@ -0,0 +1,108 @@
+import 'package:calendar_view/popup_layer/popup_layer_controller.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+
+class PopupLayer extends StatefulWidget {
+  const PopupLayer({super.key});
+
+  @override
+  State<PopupLayer> createState() => _PopupLayerState();
+}
+
+class _PopupLayerState extends State<PopupLayer> {
+  PopupLayerController popupLayerController = Get.find<PopupLayerController>();
+  GlobalKey moreSchedulePopupKey = GlobalKey();
+  @override
+  void initState() {
+    super.initState();
+    popupLayerController.onPopupMoreSchedule.addListener(_onPopupMoreSchedule);
+  }
+
+  @override
+  void dispose() {
+    super.dispose();
+    popupLayerController.onPopupMoreSchedule
+        .removeListener(_onPopupMoreSchedule);
+  }
+
+  void _onPopupMoreSchedule(e, GlobalKey key) {
+    print('onPopupMoreSchedule $key');
+    setState(() {
+      moreSchedulePopupKey = key;
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return _buildMoreSchedulePopup(moreSchedulePopupKey);
+  }
+
+  /// 只做容器而无需负责内容
+  /// [trigger] 触发器的 key
+  Widget _buildMoreSchedulePopup(GlobalKey trigger) {
+    print('触发了弹出显示更多 Key: $trigger');
+    final Size triggerSize = getWidgetSize(trigger);
+    final Offset triggerOffset = getWidgetOffset(trigger);
+    print('触发者尺寸: $triggerSize');
+    print('触发者位置: $triggerOffset');
+    final Offset popupOffset =
+        _calcPopupLayerOffset(triggerOffset, triggerSize);
+    print('计算得的弹出层位置: $popupOffset');
+    return Container(
+      decoration: BoxDecoration(
+        color: Colors.white,
+        borderRadius: BorderRadius.circular(8),
+        border: Border.all(color: Colors.black12, width: 1),
+
+        /// 简单阴影
+        boxShadow: const [
+          BoxShadow(
+            color: Colors.black12,
+            offset: Offset(3, 3),
+            blurRadius: 25,
+          ),
+        ],
+      ),
+      width: 240,
+      height: 400,
+      child: Text(popupLayerController.currMoreScheduleData.toString()),
+    );
+  }
+
+  /// 通过组件的 key 获取对应的组件的大小信息
+  /// [key] 组件的 key
+  Size getWidgetSize(GlobalKey key) {
+    try {
+      final RenderBox renderBox =
+          key.currentContext?.findRenderObject() as RenderBox;
+      return renderBox.size;
+    } catch (e) {
+      return Size.zero;
+    }
+  }
+
+  /// 通过组件的 key 获取对应的组件的位置信息
+  /// [key] 组件的 key
+  Offset getWidgetOffset(GlobalKey key) {
+    try {
+      final RenderBox renderBox =
+          key.currentContext?.findRenderObject() as RenderBox;
+      return renderBox.localToGlobal(Offset.zero);
+    } catch (e) {
+      return Offset.zero;
+    }
+  }
+
+  /// 通过触发者的位置信息和大小信息,计算弹出层的位置信息
+  /// [triggerOffset] 触发者的位置信息
+  /// [triggerSize] 触发者的大小信息
+  Offset _calcPopupLayerOffset(Offset triggerOffset, Size triggerSize) {
+    final double triggerCenterX = triggerOffset.dx + triggerSize.width / 2;
+    final double triggerCenterY = triggerOffset.dy + triggerSize.height / 2;
+    final double popupLayerWidth = 240;
+    final double popupLayerHeight = 400;
+    final double popupLayerCenterX = triggerCenterX - popupLayerWidth / 2;
+    final double popupLayerCenterY = triggerCenterY - popupLayerHeight / 2;
+    return Offset(popupLayerCenterX, popupLayerCenterY);
+  }
+}

+ 29 - 0
lib/popup_layer/popup_layer_controller.dart

@@ -0,0 +1,29 @@
+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 PopupLayerController extends GetxController {
+  PopupLayerController();
+
+  /// 弹出层【显示更多日程】事件通知
+  FEventHandler<GlobalKey> onPopupMoreSchedule = FEventHandler<GlobalKey>();
+
+  /// Popup 弹出层相关的数据
+  /// 当前需要显示更多的日程数据
+  MonthViewDayStructure currMoreScheduleData = MonthViewDayStructure(
+    index: 1,
+    date: DateTime.now(),
+  ); // 当前显示更多日程的下标
+
+  void handlePopupMoreSchedule(
+      GlobalKey key, MonthViewDayStructure moreScheduleData) {
+    currMoreScheduleData = moreScheduleData;
+    onPopupMoreSchedule.emit(this, key);
+  }
+
+  @override
+  void onInit() {
+    super.onInit();
+  }
+}