Flutter实现地图组件延伸至底部圆角Bottom Sheet下方
解决方案
要解决Bottom Sheet圆角周围的空隙问题,同时保证地图控件不被遮挡,核心思路是让地图延伸至Bottom Sheet下方,并动态适配Bottom Sheet的高度。具体实现步骤如下:
关键修改:使用Scaffold的extendBody属性+动态高度适配
将原HomePage改为StatefulWidget,通过GlobalKey获取Bottom Sheet的实际高度,给地图添加底部内边距避免控件被遮挡,同时开启extendBody让地图填满空隙:
class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { final _bottomSheetKey = GlobalKey(); double _bottomSheetHeight = 0; @override void initState() { super.initState(); // 布局完成后获取Bottom Sheet的高度 WidgetsBinding.instance.addPostFrameCallback((_) { if (_bottomSheetKey.currentContext != null) { final renderBox = _bottomSheetKey.currentContext!.findRenderObject() as RenderBox; setState(() { _bottomSheetHeight = renderBox.size.height; }); } }); } @override Widget build(BuildContext context) { return Scaffold( drawer: const NavBar(), // 核心:让body延伸至bottomSheet下方,消除空隙 extendBody: true, appBar: AppBar( foregroundColor: Colors.deepOrangeAccent, backgroundColor: Colors.white, centerTitle: true, title: const Text( 'Home', style: TextStyle(fontWeight: FontWeight.w600), ), shape: const Border( bottom: BorderSide(color: Colors.black54, width: 0.5))), // 给地图加底部padding,避免缩放按钮被Bottom Sheet遮挡 body: Padding( padding: EdgeInsets.only(bottom: _bottomSheetHeight), child: const MapWidget(), ), bottomSheet: BottomSheet( key: _bottomSheetKey, builder: (BuildContext context) => const MainBottomSheet(), onClosing: () {}, ), ); } }
原Bottom Sheet代码无需修改
你的MainBottomSheet组件的圆角、阴影样式已经符合需求,保留原代码即可:
class MainBottomSheet extends StatelessWidget { const MainBottomSheet({super.key}); @override Widget build(BuildContext context) { return Container( width: double.infinity, padding: const EdgeInsets.all(16), decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20), ), boxShadow: [ BoxShadow( color: Colors.black, blurRadius: 10, spreadRadius: 0, offset: Offset(0, 7), blurStyle: BlurStyle.normal), ]), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ RadioMenuButton( value: true, groupValue: true, onChanged: (bool? value) { if (value == true) { showModalBottomSheet( context: context, builder: (BuildContext context) => const SearchBottomSheet(), ); } }, style: ButtonStyle( shape: MaterialStatePropertyAll( RoundedRectangleBorder( borderRadius: BorderRadius.circular(20.0), ), ), ), child: const Text('Start Location'), ), const Divider(), RadioMenuButton( value: true, groupValue: true, onChanged: (bool? value) { if (value == true) { showModalBottomSheet( context: context, builder: (BuildContext context) => const SearchBottomSheet(), ); } }, style: ButtonStyle( shape: MaterialStatePropertyAll( RoundedRectangleBorder( borderRadius: BorderRadius.circular(20.0), ), ), ), child: const Text('Destination')), const Divider(), const SizedBox( height: 20, ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: ElevatedButton( onPressed: () {}, style: const ButtonStyle( backgroundColor: MaterialStatePropertyAll(Colors.deepOrangeAccent), elevation: MaterialStatePropertyAll(3), ), child: const Text( 'Find Route', style: TextStyle( color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold), ), ), ) ]), ); } }
效果说明
- 开启
extendBody: true后,地图会延伸至Bottom Sheet的下方,完全填充圆角周围的空隙; - 通过
GlobalKey动态获取Bottom Sheet的高度,避免了固定高度的适配问题; - 地图底部的内边距确保缩放按钮、Google标识等控件不会被Bottom Sheet遮挡。
内容的提问来源于stack exchange,提问作者Ahsan Irfan
相关产品推荐
相关产品推荐

