unified_popups
English · 文档中心 · API 参考 · 最佳实践
概述
Unified Popups 通过 Pop 静态 API 统一管理 Overlay 弹窗:toast、loading、confirm、sheet、flowSheet、date、menu。
核心能力
- 统一 API:全部经
Pop.*调用,类型安全 - 异步安全:
SafeOverlayEntry避免 build 阶段 setState 错误 - FlowSheet:单 Sheet 内多页栈(
push/pop/replace/completeCurrent/closeAll)+ 生命周期钩子 - Sheet 拖拽:
SheetDragDismissMode(fullBody/contentWhenAtTop/handleOnly)、拖条、键盘上移 - 返回与路由:
onBackPressed、PopScopeWidget、PopupRouteObserver(含didRemove)、dismissOnRouteChange - 多实例:除 loading 单例外可叠多层;动画时长/曲线可配
安装
dependencies:
unified_popups:
版本以 pub.dev / pubspec.yaml 为准。
初始化
必须使用同一个 navigatorKey,并注册观察者与返回拦截:
import 'package:unified_popups/unified_popups.dart';
final navigatorKey = GlobalKey<NavigatorState>();
void main() {
runApp(MyApp(navigatorKey: navigatorKey));
WidgetsBinding.instance.addPostFrameCallback((_) {
PopupManager.initialize(navigatorKey: navigatorKey);
});
}
class MyApp extends StatelessWidget {
const MyApp({required this.navigatorKey, super.key});
final GlobalKey<NavigatorState> navigatorKey;
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navigatorKey,
navigatorObservers: [PopupRouteObserver()],
builder: (context, child) => PopScopeWidget(
child: child ?? const SizedBox.shrink(),
),
home: const HomePage(),
);
}
}
基本用法
Pop.toast('保存成功', toastType: ToastType.success);
Pop.loading(message: '加载中...');
try {
await fetchData();
} finally {
Pop.hideLoading();
}
final ok = await Pop.confirm(
title: '确认删除',
content: '此操作不可撤销',
);
Sheet
final selected = await Pop.sheet<String>(
title: '筛选',
dockToEdge: true,
edgeGap: 84, // 与底部 NavigationBar 高度对齐
dragDismissMode: SheetDragDismissMode.contentWhenAtTop,
childBuilder: (dismiss) => ListTile(
title: const Text('力量'),
onTap: () => dismiss('strength'),
),
);
FlowSheet
final controller = FlowSheetController<bool>();
final done = await Pop.flowSheet<bool>(
controller: controller,
maxHeight: SheetDimension.fraction(0.9),
initialPage: StartWorkoutIntroPage(controller: controller),
);
业务页继承 FlowSheetPage / FlowSheetPageState,用 nav.push / pop / replace / completeCurrent / closeAll;结束整条流优先 completeCurrent / closeAll,避免双动画。
完整参数见 docs/API_REFERENCE.md。
Example:FitPulse
example/ 为健身健康风格演示:
| 入口 | 覆盖能力 |
|---|---|
| 今日 | toast / loading / confirm |
| 训练 | sheet(含 dockToEdge)、menu、开始训练 FlowSheet |
| 数据 | date、导出 loading |
| 我的 | 资料 sheet、健康档案 FlowSheet、设置二级页(路由关弹框) |
| Lab(AppBar ⋯) | Async / PopupManager 边界回归 |
cd example && flutter run