Flutter中如何在主页及Bottom Sheet上层显示Toast与Confetti动画
Flutter中通过showModalBottomSheet弹出的模态Bottom Sheet,本质是向根Navigator管理的Overlay栈中插入了高优先级的OverlayEntry。绝大多数Toast组件、Confetti彩纸动画默认通过当前页面的BuildContext获取父级Overlay插入浮层,插入的层级低于Bottom Sheet对应的Entry,因此会被底部弹窗遮挡,仅在主页面未被覆盖的区域可见。

通用临时修复:指定根Overlay挂载浮层
不要使用页面级context获取Overlay,改用根Navigator的context获取Overlay,保证浮层插入到所有模态路由之上:// 获取根Navigator上下文 final rootOverlayContext = Navigator.of(context, rootNavigator: true).context; // 向根Overlay插入Toast/彩纸动画的OverlayEntry即可 Overlay.of(rootOverlayContext).insert(yourFloatOverlayEntry);如果使用第三方Toast、Confetti组件,找到组件支持传入context的配置项,传入上述根context即可生效。
长期最优方案:全局浮层容器包裹根App
在应用入口处用全局浮层容器包裹整个App,所有浮层类组件统一通过全局API调用,从根源上避免路由、弹窗带来的层级遮挡问题。接入方式参考如下:void main() { runApp( MaterialApp( navigatorKey: globalFloatNavigatorKey, builder: globalFloatInit(), home: const HomePage(), ), ); }接入后所有通过全局浮层API触发的Toast、彩纸动画、自定义弹窗,默认都会展示在所有页面、Bottom Sheet、普通弹窗的最上层,不需要每次单独做层级适配。
非模态Bottom Sheet适配
如果是通过showBottomSheet弹出的非模态底部弹窗(和当前页面同路由栈)出现遮挡,只需要给页面Scaffold设置全局Key,展示浮层时通过这个Key获取Scaffold对应的Overlay即可。
注意:安卓系统原生实现的Toast属于系统级浮层,不受Flutter内部Overlay层级影响,不会被Bottom Sheet遮挡;只有纯Flutter自绘实现的Toast、动画组件才会出现这类层级遮挡问题。
内容的提问来源于stack exchange,提问作者Girija gurung

