Parcourir la source

Merge branch 'master' of http://git.ius.plus/gavin.chen/calendar_view_demo

bakamaka.guan il y a 2 ans
Parent
commit
a25f4b9b52

+ 0 - 6
lib/calendar_page/month_calendar/month_calendar_item.dart

@@ -159,12 +159,6 @@ class _MyWidgetState extends State<MonthDayItem> {
               widget.dayData,
             );
           },
-          onTapShowSchedule: (value) {
-            popupLayerController.handlePopupSchedule(
-              value,
-              widget.dayData,
-            );
-          },
         ),
       ),
     );

+ 0 - 5
lib/calendar_page/month_calendar/more_schedule_popup.dart

@@ -10,15 +10,11 @@ class MoreSchedulePopup extends StatefulWidget {
   const MoreSchedulePopup({
     Key? key,
     required this.scheduleData,
-    required this.onTapShowSchedule,
   }) : super(key: key);
 
   /// 日程数据
   final MonthViewDayStructure scheduleData;
 
-  /// 日程框详情
-  final ValueCallback? onTapShowSchedule;
-
   @override
   MoreSchedulePopupState createState() => MoreSchedulePopupState();
 }
@@ -103,7 +99,6 @@ class MoreSchedulePopupState extends State<MoreSchedulePopup> {
     return SchedualItem(
       scheduleData: schedule,
       itemHeight: _itemHeight,
-      onTapShowSchedule: widget.onTapShowSchedule,
     );
   }
 

+ 4 - 7
lib/calendar_page/month_calendar/schedule_item.dart

@@ -9,11 +9,9 @@ class SchedualItem extends StatefulWidget {
     super.key,
     required this.scheduleData,
     required this.itemHeight,
-    this.onTapShowSchedule,
   });
   final Schedule scheduleData;
   final double itemHeight;
-  final ValueCallback? onTapShowSchedule;
 
   @override
   State<SchedualItem> createState() => _SchedualItemState();
@@ -41,11 +39,9 @@ class _SchedualItemState extends State<SchedualItem> {
     _popupLayerController.onCloseSchedulePopup.removeListener(_onGlobalClick);
   }
 
-  void _onGlobalClick(e, bool isClose) {
-    if (!mounted) return;
-    print(isClose);
+  void _onGlobalClick(e, _) {
     setState(() {
-      _isSelected = isClose;
+      _isSelected = false;
     });
   }
 
@@ -63,7 +59,8 @@ class _SchedualItemState extends State<SchedualItem> {
           setState(() {
             _isSelected = !_isSelected;
           });
-          widget.onTapShowSchedule!(_scheduleListKey);
+          _popupLayerController.handlePopupScheduleDetail(
+              _scheduleListKey, schedule);
         },
 
         /// 接入双击后会导致单击反应变慢,暂时不接入

+ 0 - 5
lib/calendar_page/month_calendar/schedule_list.dart

@@ -9,7 +9,6 @@ class ScheduleList extends StatefulWidget {
     required this.maxLines,
     required this.scheduleDataList,
     required this.onTapShowMore,
-    required this.onTapShowSchedule,
   }) : super(key: key);
 
   /// 可容纳的最大日程行数
@@ -24,9 +23,6 @@ class ScheduleList extends StatefulWidget {
   /// 点击显示更多
   final VoidCallback onTapShowMore;
 
-  /// 点击显示日程卡片
-  final ValueCallback onTapShowSchedule;
-
   @override
   ScheduleListState createState() => ScheduleListState();
 }
@@ -82,7 +78,6 @@ class ScheduleListState extends State<ScheduleList> {
     return SchedualItem(
       scheduleData: schedule,
       itemHeight: widget.itemHeight,
-      onTapShowSchedule: widget.onTapShowSchedule,
     );
   }
 

+ 17 - 22
lib/calendar_page/month_calendar/schedule_popup.dart

@@ -11,29 +11,23 @@ class SchedulePopup extends StatefulWidget {
   }) : super(key: key);
 
   /// 日程数据
-  final MonthViewDayStructure scheduleData;
+  final Schedule scheduleData;
 
   @override
   SchedulePopupState createState() => SchedulePopupState();
 }
 
 class SchedulePopupState extends State<SchedulePopup> {
-  static const double _itemHeight = 28;
-  List<Schedule> _scheduleDataList = [];
   CalendarController calendarController = Get.find<CalendarController>();
   PopupLayerController popupLayerController = Get.find<PopupLayerController>();
   @override
   void initState() {
     super.initState();
-    _scheduleDataList =
-        calendarController.scheduleListFilter(widget.scheduleData.scheduleList);
   }
 
   @override
   void didUpdateWidget(covariant SchedulePopup oldWidget) {
     super.didUpdateWidget(oldWidget);
-    _scheduleDataList =
-        calendarController.scheduleListFilter(widget.scheduleData.scheduleList);
   }
 
   @override
@@ -89,7 +83,7 @@ class SchedulePopupState extends State<SchedulePopup> {
 
   /// 日程卡片视图列表
   Widget _buildScheduleList() {
-    final currentDate = widget.scheduleData.date;
+    final currentDate = widget.scheduleData.day;
     return Column(
       mainAxisSize: MainAxisSize.min,
       children: [
@@ -112,12 +106,7 @@ class SchedulePopupState extends State<SchedulePopup> {
             size: 18,
           ),
           scheduleItemWidget: Text(
-            currentDate.month.toString() +
-                '月' +
-                currentDate.day.toString() +
-                '日 周 ' +
-                weekMap[currentDate.weekday]! +
-                ' 10:00-10:30',
+            '${currentDate.month}月${currentDate.day}日 周 ${weekMap[currentDate.weekday]!} 10:00-10:30',
           ),
         ),
         _buildScheduleLayoutItem(
@@ -162,10 +151,10 @@ class SchedulePopupState extends State<SchedulePopup> {
             _buildHeadPortraitItem(),
           ],
         ),
-        SizedBox(
+        const SizedBox(
           height: 15,
         ),
-        Divider(),
+        const Divider(),
         _buildSchedulebottomActionBar(),
       ],
     );
@@ -206,10 +195,10 @@ class SchedulePopupState extends State<SchedulePopup> {
       child: Row(
         children: [
           Container(
-            margin: EdgeInsets.only(
+            margin: const EdgeInsets.only(
               left: 5,
             ),
-            child: Text('查看详情'),
+            child: const Text('查看详情'),
           ),
           Expanded(
             child: Row(
@@ -254,7 +243,7 @@ class SchedulePopupState extends State<SchedulePopup> {
   }
 
   Widget _buildHeadPortraitItem() {
-    return Container(
+    return SizedBox(
       width: 55,
       height: 55,
       child: Column(
@@ -267,11 +256,17 @@ class SchedulePopupState extends State<SchedulePopup> {
               borderRadius: BorderRadius.circular(
                 4,
               ),
-              color: Colors.red,
+              color: Color.fromARGB(255, 41, 42, 54),
             ),
+            child: const FlutterLogo(
+              size: 28,
+            ),
+          ),
+          const SizedBox(
+            height: 5,
           ),
-          Text(
-            '11222qwwqqwww2',
+          const Text(
+            '路人甲',
             overflow: TextOverflow.ellipsis,
           ),
         ],

+ 103 - 10
lib/notification_demo/global_notification_layer.dart

@@ -1,3 +1,5 @@
+import 'dart:math';
+
 import 'package:calendar_view/notification_demo/notification_card.dart';
 import 'package:calendar_view/notification_demo/notification_controller.dart';
 import 'package:flutter/material.dart';
@@ -18,8 +20,9 @@ class GlobalNotificationLayerState extends State<GlobalNotificationLayer> {
   List<SystemNotification> notifications = [];
   final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
   final ScrollController _scrollController = ScrollController();
+  static const double _notificationWidth = 420;
 
-  static final double _notificationWidth = 420;
+  bool get _isShowCloseAll => notifications.length > 2;
   @override
   void initState() {
     super.initState();
@@ -45,20 +48,61 @@ class GlobalNotificationLayerState extends State<GlobalNotificationLayer> {
     if (_listKey.currentState is! AnimatedListState) return;
     notifications.insert(index, item);
     _listKey.currentState!.insertItem(index);
+    setState(() {});
   }
 
+  // 移除消息
   void _removeNotification(index) {
     if (_listKey.currentState is! AnimatedListState) return;
+    final SystemNotification notificationToRemove = notifications[index];
+    notifications.removeAt(index);
     _listKey.currentState!.removeItem(
         index,
-        (context, animation) =>
-            _buildNotificationSizeOut(context, index, animation),
+        (context, animation) => _buildNotificationSizeOut(
+            context, index, animation, notificationToRemove),
         duration: const Duration(milliseconds: 120));
+    setState(() {});
+  }
+
+  /// 滑动式移除
+  void _removeNotificationSliderOut(index) {
+    if (_listKey.currentState is! AnimatedListState) return;
+    final SystemNotification notificationToRemove = notifications[index];
+    notifications.removeAt(index);
+    _listKey.currentState!.removeItem(
+        index,
+        (context, animation) => _buildNotificationSliderOut(
+            context, index, animation, notificationToRemove),
+        duration: const Duration(milliseconds: 200));
+    setState(() {});
+  }
+
+  /// 瞬间移除
+  void _removeNotificationInstant(index) {
+    if (_listKey.currentState is! AnimatedListState) return;
+    final SystemNotification notificationToRemove = notifications[index];
+    notifications.removeAt(index);
+    _listKey.currentState!.removeItem(
+        index,
+        (context, animation) =>
+            _buildNotificationToRemove(notificationToRemove),
+        duration: const Duration(milliseconds: 0));
+    setState(() {});
+  }
 
-    /// 延迟删除,避免动画过程中被重复删除
-    Future.delayed(const Duration(milliseconds: 120), () {
-      notifications.removeAt(index);
-    });
+  void _closeAll() {
+    final animateFrame = min(notifications.length, 8);
+    final int total = notifications.length;
+    for (var i = 0; i < total; i++) {
+      if (total - i > animateFrame) {
+        _removeNotificationInstant(0);
+      } else {
+        Future.delayed(Duration(milliseconds: 100 * (i + animateFrame - total)),
+            () {
+          _removeNotificationSliderOut(0);
+        });
+      }
+    }
   }
 
   @override
@@ -83,6 +127,8 @@ class GlobalNotificationLayerState extends State<GlobalNotificationLayer> {
             ),
           ),
         ),
+        if (_isShowCloseAll) _buildCloseAllButton()
+        // _buildCloseAllButton()
       ],
     );
   }
@@ -107,12 +153,31 @@ class GlobalNotificationLayerState extends State<GlobalNotificationLayer> {
   }
 
   /// 收缩移除
-  Widget _buildNotificationSizeOut(
-      BuildContext context, int index, Animation<double> animation) {
+  Widget _buildNotificationSizeOut(BuildContext context, int index,
+      Animation<double> animation, SystemNotification notification) {
     return SizeTransition(
       axis: Axis.vertical,
       sizeFactor: animation,
-      child: _buildNotificationCard(index),
+      child: _buildNotificationToRemove(notification),
+    );
+  }
+
+  /// 滑动移除
+  Widget _buildNotificationSliderOut(BuildContext context, int index,
+      Animation<double> animation, SystemNotification notification) {
+    return SlideTransition(
+      position: Tween<Offset>(
+        begin: const Offset(1, 0),
+        end: Offset.zero,
+      ).animate(CurvedAnimation(
+          parent: animation,
+          curve: Curves.fastOutSlowIn,
+          reverseCurve: Curves.fastOutSlowIn.flipped)),
+      child: SizeTransition(
+        axis: Axis.vertical,
+        sizeFactor: animation,
+        child: _buildNotificationToRemove(notification),
+      ),
     );
   }
 
@@ -124,4 +189,32 @@ class GlobalNotificationLayerState extends State<GlobalNotificationLayer> {
       },
     );
   }
+
+  Widget _buildNotificationToRemove(SystemNotification notification) {
+    return NotificationCard(
+      notification: notification,
+      onClose: () {},
+    );
+  }
+
+  Widget _buildCloseAllButton() {
+    return Positioned(
+      right: 20,
+      top: 20,
+      child: SizedBox(
+        height: 40,
+        child: ElevatedButton.icon(
+          style: ButtonStyle(
+            backgroundColor: MaterialStateProperty.all(
+                const Color.fromARGB(255, 238, 77, 77)),
+          ),
+          icon: const Icon(Icons.close),
+          onPressed: () {
+            _closeAll();
+          },
+          label: Text('全部关闭(${notifications.length})'),
+        ),
+      ),
+    );
+  }
 }

+ 62 - 35
lib/notification_demo/notification_card.dart

@@ -27,35 +27,9 @@ class NotificationCard extends StatelessWidget {
       child: Column(
         crossAxisAlignment: CrossAxisAlignment.start,
         children: [
+          _buildNotificationHeader(),
           Container(
-            /// 灰色下边框
-            decoration: const BoxDecoration(
-              border: Border(
-                bottom: BorderSide(
-                  color: Colors.black12,
-                  width: 1,
-                ),
-              ),
-            ),
-            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
-            child: Row(
-              children: [
-                const Icon(
-                  Icons.notifications_none,
-                  color: Colors.blue,
-                ),
-                Text(notification.title),
-                const Spacer(),
-                InkWell(
-                    onTap: () {
-                      onClose();
-                    },
-                    child: const Icon(Icons.close)),
-              ],
-            ),
-          ),
-          Container(
-            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
+            padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
             child: Text(
               notification.infoTitle,
               style: const TextStyle(
@@ -66,17 +40,70 @@ class NotificationCard extends StatelessWidget {
             ),
           ),
           ..._buildInfoContents(notification.infoItems),
+          const SizedBox(height: 12),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildNotificationHeader() {
+    return Container(
+      decoration: const BoxDecoration(
+        border: Border(
+          bottom: BorderSide(
+            color: Colors.black12,
+            width: 1,
+          ),
+        ),
+      ),
+      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
+      child: Row(
+        children: [
+          _buildIconByType(notification.type),
+          const SizedBox(width: 8),
+          Text(notification.title),
+          const Spacer(),
+          InkWell(
+              onTap: () {
+                onClose();
+              },
+              child: const Icon(Icons.close)),
         ],
       ),
     );
   }
 
+  Widget _buildIconByType(NotificationType type) {
+    switch (type) {
+      case NotificationType.notification:
+        return const Icon(
+          Icons.info_outline,
+          color: Colors.blue,
+        );
+      case NotificationType.warning:
+        return const Icon(
+          Icons.warning_amber_outlined,
+          color: Colors.orange,
+        );
+      case NotificationType.error:
+        return const Icon(
+          Icons.error_outline,
+          color: Colors.red,
+        );
+      case NotificationType.success:
+        return const Icon(
+          Icons.check_circle_outline,
+          color: Colors.green,
+        );
+    }
+  }
+
   List<Widget> _buildInfoContents(List<NotificationInfoItem> infoContents) {
     return infoContents
         .map(
           (e) => Container(
             margin: const EdgeInsets.only(bottom: 8),
-            padding: const EdgeInsets.symmetric(horizontal: 12),
+            padding: const EdgeInsets.symmetric(horizontal: 20),
             child: Row(
               children: [
                 Expanded(
@@ -84,9 +111,9 @@ class NotificationCard extends StatelessWidget {
                   child: Text(
                     e.title,
                     style: const TextStyle(
-                        color: Color.fromARGB(255, 40, 40, 40),
-                        fontSize: 14,
-                        fontWeight: FontWeight.w600),
+                      color: Color.fromARGB(255, 40, 40, 40),
+                      fontSize: 14,
+                    ),
                   ),
                 ),
                 Expanded(
@@ -94,9 +121,9 @@ class NotificationCard extends StatelessWidget {
                   child: Text(
                     e.content,
                     style: const TextStyle(
-                        color: Color.fromARGB(255, 40, 40, 40),
-                        fontSize: 14,
-                        fontWeight: FontWeight.w500),
+                      color: Color.fromARGB(255, 63, 63, 63),
+                      fontSize: 14,
+                    ),
                   ),
                 ),
               ],

+ 98 - 8
lib/notification_demo/notification_controller.dart

@@ -1,5 +1,6 @@
 import 'package:calendar_view/utils/event_type.dart';
 import 'package:get/get.dart';
+import 'dart:math';
 
 class NotificationController extends GetxController {
   NotificationController();
@@ -11,9 +12,14 @@ class NotificationController extends GetxController {
     onReceiveNotification.emit(this, notification);
   }
 
-  /// 构造一个假消息
-  void sendMockNotification() {
-    handleReceiveNotification(SystemNotification(
+  /// 取0-5的随机整数
+  int getRandomNumber() {
+    return Random().nextInt(5);
+  }
+
+  /// 各种假消息列表
+  List<SystemNotification> mockList = [
+    SystemNotification(
       title: '系统通知',
       infoTitle: '会诊将在15分钟后开始,请及时参与!',
       infoItems: [
@@ -31,11 +37,95 @@ class NotificationController extends GetxController {
         ),
       ],
       type: NotificationType.notification,
-      callback: () {
-        print('点击了详情按钮');
-      },
-      callbackButtonText: '详情',
-    ));
+    ),
+    SystemNotification(
+      title: '系统通知',
+      infoTitle: '路人甲拒绝参加你的会诊!',
+      infoItems: [
+        NotificationInfoItem(
+          title: '姓名',
+          content: '陈圆润',
+        ),
+        NotificationInfoItem(
+          title: '会诊时间',
+          content: '2021-11-11 11:11:11',
+        ),
+        NotificationInfoItem(
+          title: '拒绝原因',
+          content: '阳了',
+        ),
+      ],
+      type: NotificationType.error,
+    ),
+    SystemNotification(
+      title: '系统通知',
+      infoTitle: '路人甲拒绝了您的预约申请!',
+      infoItems: [
+        NotificationInfoItem(
+          title: '拒绝原因',
+          content: '没核酸检测报告',
+        ),
+      ],
+      type: NotificationType.error,
+    ),
+    SystemNotification(
+      title: '系统通知',
+      infoTitle: '路人甲同意了您的预约申请!!',
+      infoItems: [
+        NotificationInfoItem(
+          title: '姓名',
+          content: '陈圆润',
+        ),
+        NotificationInfoItem(
+          title: '会诊时间',
+          content: '2021-11-11 11:11:11',
+        ),
+        NotificationInfoItem(
+          title: '会诊专家',
+          content: 'Albert Einstein',
+        ),
+      ],
+      type: NotificationType.success,
+    ),
+    SystemNotification(
+      title: '系统通知',
+      infoTitle: '路人甲同意参加你的会诊!',
+      infoItems: [
+        NotificationInfoItem(
+          title: '姓名',
+          content: '陈圆润',
+        ),
+        NotificationInfoItem(
+          title: '会诊时间',
+          content: '2021-11-11 11:11:11',
+        ),
+      ],
+      type: NotificationType.success,
+    ),
+    SystemNotification(
+      title: '系统通知',
+      infoTitle: '路人甲向您发来了会诊申请!',
+      infoItems: [
+        NotificationInfoItem(
+          title: '姓名',
+          content: '陈圆润',
+        ),
+        NotificationInfoItem(
+          title: '会诊时间',
+          content: '2021-11-11 11:11:11',
+        ),
+        NotificationInfoItem(
+          title: '申请医院',
+          content: '潘达医院',
+        ),
+      ],
+      type: NotificationType.warning,
+    ),
+  ];
+
+  /// 构造一个假消息
+  void sendMockNotification() {
+    handleReceiveNotification(mockList[getRandomNumber()]);
   }
 
   @override

+ 58 - 59
lib/popup_layer/popup_layer.dart

@@ -6,6 +6,18 @@ import 'package:calendar_view/popup_layer/popup_layer_controller.dart';
 import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 
+/// 日程详情弹出框宽度
+const double _scheduleDetailPopupWidth = 380;
+
+/// 完成日程列表弹出框最小推荐宽度
+const double _moreSchedulePopupMinWidth = 220;
+
+/// 固定的头部高度
+const double _popupLayerMarginTop = 70;
+
+/// 固定的左侧宽度
+const double _popupLayerMarginLeft = 240;
+
 class PopupLayer extends StatefulWidget {
   const PopupLayer({super.key});
 
@@ -17,16 +29,31 @@ class _PopupLayerState extends State<PopupLayer> {
   PopupLayerController popupLayerController = Get.find<PopupLayerController>();
   bool _isShowMoreSchedulePopup = false;
   bool _isNeedCloseMoreSchedulePopup = false;
-  bool _isShowSchedulePopup = false;
-  bool _isNeedCloseSchedulePopup = false;
+  bool _isShowScheduleDetailPopup = false;
+  bool _isNeedCloseScheduleDetailPopup = false;
   GlobalKey moreSchedulePopupKey = GlobalKey();
-  GlobalKey schedulePopupKey = GlobalKey();
+  GlobalKey scheduleDetailPopupKey = GlobalKey();
+
+  /// 弹出框装饰器
+  static final BoxDecoration _popupBoxDecoration = 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,
+      ),
+    ],
+  );
   @override
   void initState() {
     super.initState();
     popupLayerController.onPopupMoreSchedule.addListener(_onPopupMoreSchedule);
     popupLayerController.onGlobalClick.addListener(_onGlobalClick);
-    popupLayerController.onPopupSchedule.addListener(_onPopupSchedule);
+    popupLayerController.onPopupScheduleDatail
+        .addListener(_onPopupScheduleDatail);
   }
 
   @override
@@ -35,7 +62,8 @@ class _PopupLayerState extends State<PopupLayer> {
     popupLayerController.onPopupMoreSchedule
         .removeListener(_onPopupMoreSchedule);
     popupLayerController.onGlobalClick.removeListener(_onGlobalClick);
-    popupLayerController.onPopupSchedule.removeListener(_onPopupSchedule);
+    popupLayerController.onPopupScheduleDatail
+        .removeListener(_onPopupScheduleDatail);
   }
 
   /// 收到显示更多日程的事件
@@ -46,11 +74,11 @@ class _PopupLayerState extends State<PopupLayer> {
     });
   }
 
-  /// 收到显示日程的事件
-  void _onPopupSchedule(e, GlobalKey key) {
+  /// 收到显示日程详情的事件
+  void _onPopupScheduleDatail(e, GlobalKey key) {
     setState(() {
-      _isShowSchedulePopup = true;
-      schedulePopupKey = key;
+      _isShowScheduleDetailPopup = true;
+      scheduleDetailPopupKey = key;
     });
   }
 
@@ -61,17 +89,18 @@ class _PopupLayerState extends State<PopupLayer> {
   void _onGlobalClick(e, PointerEvent event) {
     if (event is PointerDownEvent) {
       _isNeedCloseMoreSchedulePopup = true;
-      _isNeedCloseSchedulePopup = true;
+      _isNeedCloseScheduleDetailPopup = true;
     } else if (event is PointerUpEvent) {
       if (_isNeedCloseMoreSchedulePopup) {
         setState(() {
           _isShowMoreSchedulePopup = false;
         });
       }
-      if (_isNeedCloseSchedulePopup) {
+      if (_isNeedCloseScheduleDetailPopup) {
         setState(() {
-          _isShowSchedulePopup = false;
+          _isShowScheduleDetailPopup = false;
         });
+        popupLayerController.onCloseSchedulePopup.emit(this, null);
       }
     }
   }
@@ -88,16 +117,15 @@ class _PopupLayerState extends State<PopupLayer> {
             },
             child: _buildMoreSchedulePopup(moreSchedulePopupKey),
           ),
-        if (_isShowSchedulePopup)
+        if (_isShowScheduleDetailPopup)
           Listener(
             behavior: HitTestBehavior.deferToChild,
             onPointerUp: (event) {
               setState(() {
-                _isNeedCloseSchedulePopup = false;
+                _isNeedCloseScheduleDetailPopup = false;
               });
-              popupLayerController.onCloseSchedulePopup.emit(this, false);
             },
-            child: _buildSchedulePopup(schedulePopupKey),
+            child: _buildScheduleDetailPopup(scheduleDetailPopupKey),
           )
       ],
     );
@@ -112,27 +140,10 @@ class _PopupLayerState extends State<PopupLayer> {
       delegate: AutoAlignFlowDelegate(triggerOffset),
       children: [
         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: max(triggerSize.width, 220),
+          decoration: _popupBoxDecoration,
+          width: max(triggerSize.width, _moreSchedulePopupMinWidth),
           child: MoreSchedulePopup(
             scheduleData: popupLayerController.currMoreScheduleData,
-            onTapShowSchedule: (value) {
-              popupLayerController.handlePopupSchedule(
-                value,
-                popupLayerController.currMoreScheduleData,
-              );
-            },
           ),
         ),
       ],
@@ -141,39 +152,27 @@ class _PopupLayerState extends State<PopupLayer> {
 
   /// 只做容器而无需负责内容
   /// [trigger] 触发器的 key
-  Widget _buildSchedulePopup(GlobalKey trigger) {
+  Widget _buildScheduleDetailPopup(GlobalKey trigger) {
     final Size triggerSize = getWidgetSize(trigger);
     final Offset triggerOffset = getWidgetOffset(trigger);
     return Flow(
       delegate: ScheduleAutoAlignFlowDelegate(triggerOffset, triggerSize),
       children: [
         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: 360,
-          child: SchedulePopup(
-            scheduleData: popupLayerController.currMoreScheduleData,
+          padding: const EdgeInsets.symmetric(horizontal: 10),
+          width: _scheduleDetailPopupWidth,
+          child: Container(
+            decoration: _popupBoxDecoration,
+            child: SchedulePopup(
+              scheduleData: popupLayerController.currScheduleData,
+            ),
           ),
         ),
       ],
     );
   }
 
-  static const double _popupLayerMarginTop = 70;
-  static const double _popupLayerMarginLeft = 240;
-
   /// 通过组件的 key 获取对应的组件的大小信息
-  /// [key] 组件的 key
   Size getWidgetSize(GlobalKey key) {
     try {
       final RenderBox renderBox =
@@ -186,7 +185,6 @@ class _PopupLayerState extends State<PopupLayer> {
   }
 
   /// 通过组件的 key 获取对应的组件在弹出层的位置
-  /// [key] 组件的 key
   Offset getWidgetOffset(GlobalKey key) {
     try {
       final RenderBox renderBox =
@@ -243,10 +241,11 @@ class ScheduleAutoAlignFlowDelegate extends FlowDelegate {
       if (containerSize.height - y < childSize.height) {
         y = containerSize.height - childSize.height;
       }
-      if (containerSize.width < x + childSize.width + 370) {
-        x = x - 370;
+      if (containerSize.width <
+          x + childSize.width + _scheduleDetailPopupWidth) {
+        x = x - _scheduleDetailPopupWidth;
       } else {
-        x = x + triggerSize.width + 10;
+        x = x + triggerSize.width;
       }
       context.paintChild(i, transform: Matrix4.translationValues(x, y, 0));
     }

+ 26 - 7
lib/popup_layer/popup_layer_controller.dart

@@ -10,20 +10,40 @@ class PopupLayerController extends GetxController {
   FEventHandler<GlobalKey> onPopupMoreSchedule = FEventHandler<GlobalKey>();
 
   /// 弹出层【显示日程详情】事件通知
-  FEventHandler<GlobalKey> onPopupSchedule = FEventHandler<GlobalKey>();
+  FEventHandler<GlobalKey> onPopupScheduleDatail = FEventHandler<GlobalKey>();
 
   /// 全局点击事件通知
   FEventHandler<PointerEvent> onGlobalClick = FEventHandler<PointerEvent>();
 
   /// 关闭日程弹窗 事件通知
-  FEventHandler<bool> onCloseSchedulePopup = FEventHandler<bool>();
+  FEventHandler<void> onCloseSchedulePopup = FEventHandler<void>();
 
   /// Popup 弹出层相关的数据
   /// 当前需要显示更多的日程数据
   MonthViewDayStructure currMoreScheduleData = MonthViewDayStructure(
     index: 1,
     date: DateTime.now(),
-  ); // 当前显示更多日程的下标
+  );
+
+  // 填充
+  //  final String title; // 日程标题
+  // final String content; // 日程内容
+  // final DateTime day; // 日程日期
+  // final ScheduleType type; // 日程类型
+  // final DateTime? startTime; // 日程开始时间
+  // final DateTime? endTime; // 日程结束时间
+  Schedule currScheduleData = Schedule(
+    title: 'title',
+    content: 'content',
+    day: DateTime.now(),
+    type: ScheduleType(
+      typeName: 'typeName',
+      isSelected: true,
+      color: Colors.red,
+    ),
+    startTime: DateTime.now(),
+    endTime: DateTime.now(),
+  );
 
   void handlePopupMoreSchedule(
       GlobalKey key, MonthViewDayStructure moreScheduleData) {
@@ -31,10 +51,9 @@ class PopupLayerController extends GetxController {
     onPopupMoreSchedule.emit(this, key);
   }
 
-  void handlePopupSchedule(
-      GlobalKey key, MonthViewDayStructure moreScheduleData) {
-    currMoreScheduleData = moreScheduleData;
-    onPopupSchedule.emit(this, key);
+  void handlePopupScheduleDetail(GlobalKey key, Schedule scheduleData) {
+    currScheduleData = scheduleData;
+    onPopupScheduleDatail.emit(this, key);
   }
 
   @override