如何在用户上滑DraggableScrollableSheet时仅添加背景模糊效果
实现DraggableScrollableSheet仅上滑时显示背景模糊
核心思路
把组件改为状态组件,通过监听Sheet的滑动状态动态控制模糊效果:
- 维护一个布尔状态
_isBlurred,初始为false(对应Sheet初始的最小高度状态) - 监听Sheet的滑动通知,当Sheet当前高度超过初始高度时,开启模糊;回到初始高度时关闭模糊
- 根据状态动态调整
BackdropFilter的模糊参数,非模糊状态下sigma值设为0
完整代码
class BlurredSheetDemo extends StatefulWidget { const BlurredSheetDemo({super.key}); @override State<BlurredSheetDemo> createState() => _BlurredSheetDemoState(); } class _BlurredSheetDemoState extends State<BlurredSheetDemo> { bool _isBlurred = false; final double _initialSheetSize = 0.25; @override Widget build(BuildContext context) { return Stack( children: [ // 这里放置你的背景内容(比如图片、其他组件) const Center(child: Text("背景内容区域")), NotificationListener<DraggableScrollableNotification>( onNotification: (notification) { setState(() { // 当Sheet高度超过初始值时,触发模糊 _isBlurred = notification.extent > _initialSheetSize; }); return true; }, child: DraggableScrollableSheet( initialChildSize: _initialSheetSize, minChildSize: _initialSheetSize, maxChildSize: 0.55, expand: true, builder: (context, scrollController) => BackdropFilter( filter: ImageFilter.blur( sigmaX: _isBlurred ? 2 : 0, sigmaY: _isBlurred ? 2 : 0, ), child: Container( decoration: const BoxDecoration( color: Colors.green, borderRadius: BorderRadius.only( topLeft: Radius.circular(30), topRight: Radius.circular(30), ), ), child: Padding( padding: const EdgeInsets.only(top: 30, left: 10, right: 10), child: ListView.builder( controller: scrollController, itemCount: 25, itemBuilder: (BuildContext context, int index) { return Card( child: ListTile(title: Text('Item $index')), ); }, ), ), ), ), ), ), ], ); } }
关键说明
NotificationListener<DraggableScrollableNotification>:用来捕获Sheet的滑动状态,notification.extent代表当前Sheet高度占屏幕的比例- 动态调整模糊参数:通过
_isBlurred状态切换sigma值,避免非滑动状态下背景被不必要地模糊 - 保持初始状态一致性:初始时Sheet处于最小高度,
_isBlurred为false,背景无模糊效果
内容的提问来源于stack exchange,提问作者xhanalexander
相关产品推荐
相关产品推荐

