参考React Native案例,如何在Flutter中实现Bottom Sheet背景缩放效果?
Flutter实现Bottom Sheet背景缩放效果
要实现类似React Native中Bottom Sheet展开时背景缩放的效果,我们可以利用Flutter的DraggableScrollableSheet组件结合Transform.scale动态控制背景元素的缩放,核心逻辑是监听底部弹窗的拖拽进度,实时调整背景的缩放比例。
实现代码示例
import 'package:flutter/material.dart'; class BackgroundZoomBottomSheet extends StatefulWidget { const BackgroundZoomBottomSheet({super.key}); @override State<BackgroundZoomBottomSheet> createState() => _BackgroundZoomBottomSheetState(); } class _BackgroundZoomBottomSheetState extends State<BackgroundZoomBottomSheet> { // 弹窗收起时背景处于放大状态,初始缩放值设为1.2 double _backgroundScale = 1.2; @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ // 可动态缩放的背景层 Transform.scale( scale: _backgroundScale, alignment: Alignment.center, child: Image.network( 'https://picsum.photos/1080/1920', fit: BoxFit.cover, height: double.infinity, width: double.infinity, ), ), // 监听弹窗拖拽进度,更新背景缩放 NotificationListener<DraggableScrollableNotification>( onNotification: (notification) { // 将弹窗的extent范围转换为0-1的拖拽进度比例 final progress = (notification.extent - notification.minExtent) / (notification.maxExtent - notification.minExtent); // 随弹窗展开,背景从1.2逐步缩小到1 setState(() { _backgroundScale = 1.2 - (progress * 0.2); }); return true; }, child: DraggableScrollableSheet( initialChildSize: 0.3, // 弹窗初始高度占可用空间30% minChildSize: 0.3, // 弹窗最小高度占比 maxChildSize: 0.9, // 弹窗最大高度占比 builder: (context, scrollController) { return Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), child: ListView.builder( controller: scrollController, itemCount: 20, itemBuilder: (context, index) => ListTile(title: Text('列表项 $index')), ), ); }, ), ), ], ), ); } }
关键细节说明
- 层级结构:通过
Stack将背景图和底部弹窗叠加,确保背景图处于底层,缩放时不会遮挡弹窗。 - 缩放逻辑:使用
Transform.scale组件动态修改scale值,结合setState触发UI更新。 - 进度映射:借助
DraggableScrollableNotification获取弹窗的拖拽进度,将其转换为0-1的比例后,映射到背景缩放值的变化区间。 - 自定义调整:
- 若需要背景随弹窗展开而放大,可将缩放公式改为
_backgroundScale = 1 + (progress * 0.2),初始值设为1。 - 修改
initialChildSize、minChildSize、maxChildSize可调整弹窗的初始高度和拖拽范围。 - 调整
_backgroundScale的初始值和变化幅度,能改变背景缩放的视觉强度。
- 若需要背景随弹窗展开而放大,可将缩放公式改为
内容的提问来源于stack exchange,提问作者Riri
相关产品推荐
相关产品推荐

