Flutter应用两处背景模糊实现求助:悬浮按钮菜单与底部弹窗
解决Flutter两处背景模糊问题
一、flutter_speed_dial 展开时添加背景模糊
- 维护展开状态变量
在页面的State类中添加布尔变量跟踪Speed Dial的展开状态:
bool _isDialOpen = false;
- 用Stack叠加内容与模糊层
将原页面内容和模糊层放入Stack,根据状态控制模糊层显示:
@override Widget build(BuildContext context) { return Stack( children: [ // 原页面主内容 Scaffold( appBar: AppBar(title: const Text("Demo")), body: const Center(child: Text("主内容区域")), floatingActionButton: SpeedDial( icon: Icons.add, activeIcon: Icons.close, onOpen: () => setState(() => _isDialOpen = true), onClose: () => setState(() => _isDialOpen = false), children: [ SpeedDialChild(child: const Icon(Icons.edit), label: "编辑"), SpeedDialChild(child: const Icon(Icons.delete), label: "删除"), ], ), ), // 背景模糊层(仅在展开时显示) if (_isDialOpen) GestureDetector( onTap: () => setState(() => _isDialOpen = false), // 点击模糊层关闭菜单 child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 3, sigmaY: 3), child: Container( width: double.infinity, height: double.infinity, color: Colors.black.withOpacity(0.3), // 叠加半透明黑增强氛围感 ), ), ), ], ); }
二、BottomSheet 背景模糊不覆盖自身
问题出在模糊层与BottomSheet内容的层级关系,需将模糊层放在内容下方:
- 修改全局
showChiscoBottomSheet方法
Future<T?> showChiscoBottomSheet<T>({ required BuildContext context, required Widget child, }) { return showModalBottomSheet<T>( context: context, backgroundColor: Colors.transparent, // 必须设为透明,让底层模糊层可见 isScrollControlled: true, // 根据需求调整,比如需要适配键盘时开启 builder: (context) { return Stack( children: [ // 全屏模糊层 GestureDetector( onTap: () => Navigator.pop(context), // 点击模糊层关闭BottomSheet child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 2, sigmaY: 2), child: const SizedBox.expand(), ), ), // BottomSheet 实际内容(固定在屏幕底部) Positioned( bottom: 0, left: 0, right: 0, child: Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(16), topRight: Radius.circular(16), ), ), padding: const EdgeInsets.all(16), child: child, ), ), ], ); }, ); }
- 调用示例
ElevatedButton( onPressed: () { showChiscoBottomSheet( context: context, child: const Column( mainAxisSize: MainAxisSize.min, children: [ Text("BottomSheet 标题"), SizedBox(height: 16), Text("这部分内容不会被模糊覆盖"), ], ), ); }, child: const Text("打开BottomSheet"), )
内容的提问来源于stack exchange,提问作者MehdiAbolhassani
相关产品推荐
相关产品推荐

