Flutter中Google Maps设置:如何让地图仅在屏幕上半部分居中
实现Google地图在上半部分居中显示(适配底部弹窗)
核心思路
因为底部弹窗(Bottom Sheet)占据了屏幕下半区域,地图的可视范围被限制在上半部分。要让目标点位始终居中于可视区域,需要将地图相机的目标屏幕位置调整至上半部分的中心,而非默认的屏幕整体中心。
具体实现步骤
- 获取屏幕尺寸与弹窗高度:拿到当前屏幕宽高,以及你设定的Bottom Sheet固定高度。
- 计算上半部分的中心屏幕坐标:用屏幕总高度减去弹窗高度,算出上半区域的垂直中心位置。
- 调整地图相机位置:使用Google Maps插件提供的
newLatLngWithTargetScreenCoordinate方法,将目标点位定位到计算好的上半部分中心坐标。
完整代码示例
1. 布局结构(地图+底部弹窗)
import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; class MapWithBottomSheet extends StatefulWidget { const MapWithBottomSheet({super.key}); @override State<MapWithBottomSheet> createState() => _MapWithBottomSheetState(); } class _MapWithBottomSheetState extends State<MapWithBottomSheet> { late MapController _mapController; // 固定Bottom Sheet高度,可根据需求调整 static const _bottomSheetHeight = 300.0; @override void initState() { super.initState(); _mapController = MapController(); } // 将目标点位居中到地图上半部分 void _centerMapToUpperHalf(LatLng targetLocation) { final screenSize = MediaQuery.of(context).size; // 计算上半部分的垂直中心坐标 final upperHalfCenterY = (screenSize.height - _bottomSheetHeight) / 2; // 目标屏幕坐标:水平居中,垂直为上半部分中心 final targetScreenOffset = Offset( screenSize.width / 2, upperHalfCenterY, ); // 创建相机更新指令 final cameraUpdate = CameraUpdate.newLatLngWithTargetScreenCoordinate( targetLocation, targetScreenOffset, ); // 移动地图相机 _mapController.moveCamera(cameraUpdate); // 如果需要指定缩放级别,可以先设置缩放再调整位置 // await _mapController.animateCamera(CameraUpdate.newLatLngZoom(targetLocation, 15)); // await _mapController.animateCamera(cameraUpdate); } @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ // 地图组件,占满整个屏幕 GoogleMap( controller: _mapController, initialCameraPosition: const CameraPosition( target: LatLng(37.7749, -122.4194), // 初始示例位置 zoom: 12, ), onMapCreated: (controller) { // 地图初始化完成后,可测试居中功能 _centerMapToUpperHalf(const LatLng(37.7749, -122.4194)); }, ), // 底部固定弹窗 Positioned( bottom: 0, left: 0, right: 0, height: _bottomSheetHeight, child: BottomSheet( onClosing: () {}, builder: (_) => Container( color: Colors.white, padding: const EdgeInsets.all(16), child: Column( children: [ const Text('底部弹窗内容'), ElevatedButton( onPressed: () { // 测试:点击按钮将地图居中到新点位 _centerMapToUpperHalf(const LatLng(37.7898, -122.401)); }, child: const Text('切换目标点位'), ), ], ), ), ), ), ], ), ); } }
2. 动态弹窗的适配(可选)
如果你的Bottom Sheet是可拖动的动态高度,需要监听其高度变化,实时重新计算并更新地图相机位置:
- 使用
DraggableScrollableSheet替代固定高度的Bottom Sheet - 通过
DraggableScrollableController获取当前弹窗的高度比例,计算实际高度后重新调用_centerMapToUpperHalf方法
注意事项
- 确保在地图初始化完成(
onMapCreated回调)后再调用相机调整方法,避免控制器未就绪的问题。 - 如果需要同时设置缩放级别,建议先执行缩放操作,再调整点位的屏幕位置,避免偏移计算出错。
内容的提问来源于stack exchange,提问作者stcojo
相关产品推荐
相关产品推荐

