# OneApp Popup - 弹窗管理模块 ## 模块概述 `oneapp_popup` 是 OneApp 的统一弹窗管理模块,提供了全局弹窗管理、优先级控制、样式定制和生命周期管理等功能。该模块确保应用中所有弹窗的一致性体验,避免弹窗冲突,并提供灵活的弹窗展示策略。 ## 核心功能 ### 1. 统一弹窗管理 - **全局队列**:统一管理所有弹窗显示队列 - **弹窗注册**:注册和管理不同类型的弹窗 - **显示控制**:控制弹窗的显示和隐藏 - **状态管理**:跟踪弹窗的显示状态 ### 2. 弹窗优先级控制 - **优先级排序**:按优先级排序弹窗显示顺序 - **抢占机制**:高优先级弹窗抢占显示 - **队列管理**:智能管理弹窗等待队列 - **冲突解决**:解决弹窗显示冲突 ### 3. 弹窗样式定制 - **主题适配**:自动适配应用主题 - **样式继承**:支持样式继承和覆盖 - **动画效果**:丰富的弹窗动画效果 - **响应式设计**:适配不同屏幕尺寸 ### 4. 弹窗生命周期 - **生命周期钩子**:完整的生命周期回调 - **自动销毁**:弹窗自动销毁机制 - **内存管理**:防止内存泄漏 - **状态恢复**:应用重启后状态恢复 ## 技术架构 ### 架构设计 ``` ┌─────────────────────────────────────┐ │ 应用界面层 │ │ (Application UI) │ ├─────────────────────────────────────┤ │ OneApp Popup │ │ ┌──────────┬──────────┬──────────┐ │ │ │ 弹窗管理 │ 队列控制 │ 样式系统 │ │ │ ├──────────┼──────────┼──────────┤ │ │ │ 生命周期 │ 事件系统 │ 动画引擎 │ │ │ └──────────┴──────────┴──────────┘ │ ├─────────────────────────────────────┤ │ UI 渲染层 │ │ ┌──────────┬──────────┬──────────┐ │ │ │ Overlay │ Dialog │ BottomSheet │ │ └──────────┴──────────┴──────────┘ │ ├─────────────────────────────────────┤ │ Flutter Framework │ │ (Widget System) │ └─────────────────────────────────────┘ ``` ### 核心组件 #### 1. 弹窗管理器 (PopupManager) ```dart class PopupManager { // 显示弹窗 Future show(Popup popup); // 隐藏弹窗 Future hide(String popupId); // 隐藏所有弹窗 Future hideAll(); // 获取当前弹窗 Popup? getCurrentPopup(); // 获取弹窗队列 List getPopupQueue(); } ``` #### 2. 弹窗队列控制器 (PopupQueueController) ```dart class PopupQueueController { // 添加弹窗到队列 void enqueue(Popup popup); // 从队列移除弹窗 bool dequeue(String popupId); // 按优先级排序队列 void sortByPriority(); // 处理下一个弹窗 Future processNext(); } ``` #### 3. 弹窗样式管理器 (PopupStyleManager) ```dart class PopupStyleManager { // 应用弹窗主题 PopupTheme applyTheme(PopupStyle style, AppTheme theme); // 创建弹窗样式 PopupStyle createStyle(PopupType type); // 自定义样式 PopupStyle customizeStyle(PopupStyle base, StyleOverrides overrides); // 获取默认样式 PopupStyle getDefaultStyle(PopupType type); } ``` #### 4. 弹窗生命周期管理器 (PopupLifecycleManager) ```dart class PopupLifecycleManager { // 注册生命周期监听器 void registerLifecycleListener(String popupId, PopupLifecycleListener listener); // 触发生命周期事件 void triggerLifecycleEvent(String popupId, PopupLifecycleEvent event); // 清理弹窗资源 void cleanupPopup(String popupId); // 恢复弹窗状态 Future restorePopupState(); } ``` ## 数据模型 ### 弹窗模型 ```dart class Popup { final String id; final PopupType type; final Widget content; final PopupPriority priority; final PopupStyle? style; final PopupOptions options; final Map data; final DateTime createdAt; final Duration? autoHideDelay; final List actions; } enum PopupType { dialog, // 对话框 bottomSheet, // 底部弹窗 toast, // 吐司消息 overlay, // 覆盖层 modal, // 模态框 banner, // 横幅 snackbar // 快捷消息 } enum PopupPriority { low, // 低优先级 normal, // 普通优先级 high, // 高优先级 critical, // 关键优先级 emergency // 紧急优先级 } ``` ### 弹窗样式模型 ```dart class PopupStyle { final Color? backgroundColor; final BorderRadius? borderRadius; final EdgeInsets? padding; final EdgeInsets? margin; final BoxShadow? shadow; final TextStyle? textStyle; final PopupAnimation? animation; final Alignment? alignment; final Size? size; final bool? barrierDismissible; } class PopupAnimation { final AnimationType type; final Duration duration; final Curve curve; final Offset? slideDirection; final double? scaleStart; } enum AnimationType { fade, // 淡入淡出 slide, // 滑动 scale, // 缩放 rotate, // 旋转 bounce, // 弹跳 none // 无动画 } ``` ### 弹窗选项模型 ```dart class PopupOptions { final bool barrierDismissible; final Color? barrierColor; final String? barrierLabel; final bool useRootNavigator; final RouteSettings? routeSettings; final Offset? anchorPoint; final PopupGravity gravity; final Duration? showDuration; final Duration? hideDuration; } enum PopupGravity { center, // 居中 top, // 顶部 bottom, // 底部 left, // 左侧 right, // 右侧 topLeft, // 左上 topRight, // 右上 bottomLeft, // 左下 bottomRight // 右下 } ``` ## API 接口 ### 弹窗管理接口 ```dart abstract class PopupService { // 显示弹窗 Future> showPopup(ShowPopupRequest request); // 隐藏弹窗 Future> hidePopup(HidePopupRequest request); // 获取弹窗状态 Future> getPopupStatus(String popupId); // 清理弹窗 Future> clearPopups(ClearPopupsRequest request); } ``` ### 弹窗样式接口 ```dart abstract class PopupStyleService { // 获取弹窗主题 Future> getPopupTheme(String themeId); // 更新弹窗样式 Future> updatePopupStyle(UpdateStyleRequest request); // 获取样式模板 Future>> getStyleTemplates(); } ``` ## 配置管理 ### 弹窗配置 ```dart class PopupConfig { final int maxConcurrentPopups; final Duration defaultAnimationDuration; final bool enableGlobalQueue; final bool autoHideOnAppBackground; final Map typeConfigs; final PopupTheme defaultTheme; static const PopupConfig defaultConfig = PopupConfig( maxConcurrentPopups: 3, defaultAnimationDuration: Duration(milliseconds: 300), enableGlobalQueue: true, autoHideOnAppBackground: true, typeConfigs: { PopupType.dialog: PopupTypeConfig( maxInstances: 1, defaultPriority: PopupPriority.high, ), PopupType.toast: PopupTypeConfig( maxInstances: 5, defaultPriority: PopupPriority.low, ), }, defaultTheme: PopupTheme.defaultTheme, ); } ``` ### 主题配置 ```dart class PopupTheme { final PopupStyle dialogStyle; final PopupStyle toastStyle; final PopupStyle bottomSheetStyle; final PopupStyle overlayStyle; final Map customStyles; static const PopupTheme defaultTheme = PopupTheme( dialogStyle: PopupStyle( backgroundColor: Colors.white, borderRadius: BorderRadius.circular(8.0), padding: EdgeInsets.all(16.0), animation: PopupAnimation( type: AnimationType.scale, duration: Duration(milliseconds: 300), ), ), toastStyle: PopupStyle( backgroundColor: Colors.black87, borderRadius: BorderRadius.circular(24.0), padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), animation: PopupAnimation( type: AnimationType.slide, duration: Duration(milliseconds: 200), ), ), ); } ``` ## 使用示例 ### 基本弹窗显示 ```dart // 显示对话框 final result = await PopupManager.instance.show( Popup( id: 'confirm_dialog', type: PopupType.dialog, priority: PopupPriority.high, content: AlertDialog( title: Text('确认操作'), content: Text('是否确认执行此操作?'), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: Text('取消'), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: Text('确认'), ), ], ), ), ); if (result == true) { print('用户确认操作'); } ``` ### 吐司消息 ```dart // 显示成功消息 PopupManager.instance.show( Popup( id: 'success_toast', type: PopupType.toast, priority: PopupPriority.normal, content: Container( padding: EdgeInsets.all(16.0), decoration: BoxDecoration( color: Colors.green, borderRadius: BorderRadius.circular(8.0), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.check, color: Colors.white), SizedBox(width: 8.0), Text('操作成功', style: TextStyle(color: Colors.white)), ], ), ), options: PopupOptions( gravity: PopupGravity.top, barrierDismissible: false, ), autoHideDelay: Duration(seconds: 3), ), ); ``` ### 底部弹窗 ```dart // 显示底部选择弹窗 final selectedOption = await PopupManager.instance.show( Popup( id: 'bottom_sheet_options', type: PopupType.bottomSheet, priority: PopupPriority.normal, content: Column( mainAxisSize: MainAxisSize.min, children: [ ListTile( leading: Icon(Icons.camera), title: Text('拍照'), onTap: () => Navigator.of(context).pop('camera'), ), ListTile( leading: Icon(Icons.photo_library), title: Text('从相册选择'), onTap: () => Navigator.of(context).pop('gallery'), ), ListTile( leading: Icon(Icons.cancel), title: Text('取消'), onTap: () => Navigator.of(context).pop(null), ), ], ), style: PopupStyle( backgroundColor: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(16.0)), ), ), ); print('用户选择: $selectedOption'); ``` ### 自定义弹窗样式 ```dart // 创建自定义样式弹窗 final customStyle = PopupStyle( backgroundColor: Colors.blue.shade50, borderRadius: BorderRadius.circular(12.0), padding: EdgeInsets.all(20.0), shadow: BoxShadow( color: Colors.black26, blurRadius: 10.0, offset: Offset(0, 4), ), animation: PopupAnimation( type: AnimationType.bounce, duration: Duration(milliseconds: 500), curve: Curves.elasticOut, ), ); PopupManager.instance.show( Popup( id: 'custom_popup', type: PopupType.modal, priority: PopupPriority.high, style: customStyle, content: Container( width: 300, child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.info, size: 48, color: Colors.blue), SizedBox(height: 16), Text('自定义弹窗', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), SizedBox(height: 8), Text('这是一个自定义样式的弹窗示例'), SizedBox(height: 16), ElevatedButton( onPressed: () => PopupManager.instance.hide('custom_popup'), child: Text('关闭'), ), ], ), ), ), ); ``` ### 弹窗队列管理 ```dart // 批量添加弹窗到队列 final popups = [ Popup( id: 'popup_1', type: PopupType.toast, priority: PopupPriority.low, content: Text('消息1'), ), Popup( id: 'popup_2', type: PopupType.dialog, priority: PopupPriority.high, content: Text('重要消息'), ), Popup( id: 'popup_3', type: PopupType.toast, priority: PopupPriority.normal, content: Text('消息3'), ), ]; // 按优先级添加到队列 for (final popup in popups) { PopupManager.instance.enqueue(popup); } // 监听弹窗队列变化 PopupManager.instance.onQueueChanged.listen((queue) { print('当前队列长度: ${queue.length}'); }); ``` ## 测试策略 ### 单元测试 ```dart group('PopupManager Tests', () { test('should show popup successfully', () async { // Given final popupManager = PopupManager(); final popup = Popup( id: 'test_popup', type: PopupType.dialog, content: Text('Test'), ); // When final result = await popupManager.show(popup); // Then expect(popupManager.getCurrentPopup()?.id, 'test_popup'); }); test('should manage popup queue by priority', () { // Given final queueController = PopupQueueController(); final lowPriorityPopup = Popup(id: 'low', priority: PopupPriority.low); final highPriorityPopup = Popup(id: 'high', priority: PopupPriority.high); // When queueController.enqueue(lowPriorityPopup); queueController.enqueue(highPriorityPopup); queueController.sortByPriority(); // Then final queue = queueController.getQueue(); expect(queue.first.id, 'high'); expect(queue.last.id, 'low'); }); }); ``` ### 集成测试 ```dart group('Popup Integration Tests', () { testWidgets('popup display flow', (tester) async { // 1. 显示弹窗 await PopupManager.instance.show(testPopup); await tester.pumpAndSettle(); // 2. 验证弹窗显示 expect(find.byKey(Key('test_popup')), findsOneWidget); // 3. 点击关闭按钮 await tester.tap(find.byKey(Key('close_button'))); await tester.pumpAndSettle(); // 4. 验证弹窗关闭 expect(find.byKey(Key('test_popup')), findsNothing); }); }); ``` ## 性能优化 ### 渲染优化 - **懒加载**:弹窗内容懒加载 - **复用机制**:弹窗组件复用 - **动画优化**:高效的动画实现 - **内存管理**:及时释放弹窗资源 ### 队列优化 - **智能调度**:智能弹窗调度算法 - **优先级合并**:相同优先级弹窗合并 - **批量处理**:批量处理弹窗队列 - **负载控制**:控制同时显示的弹窗数量 ## 版本历史 ### v0.3.1+2 (当前版本) - 新增弹窗主题系统 - 优化动画性能 - 支持自定义弹窗样式 - 修复内存泄漏问题 ### v0.3.0 - 重构弹窗管理架构 - 新增优先级队列系统 - 支持多种弹窗类型 - 改进生命周期管理 ## 依赖关系 ### 内部依赖 - `basic_theme`: 主题管理系统 - `basic_utils`: 工具类库 - `basic_logger`: 日志记录 ### 外部依赖 - `flutter/material`: Material 设计组件 - `flutter/cupertino`: iOS 风格组件 - `rxdart`: 响应式编程支持 ## 总结 `oneapp_popup` 模块为 OneApp 提供了完整的弹窗管理解决方案。通过统一的弹窗管理、智能的优先级控制、灵活的样式定制和完善的生命周期管理,该模块确保了应用中所有弹窗的一致性体验,提高了用户界面的专业性和用户体验的流畅性。