Flutter Map模态框中无法获取MapController问题求助
解决Flutter Map模态框中调用MapController失败的问题
问题原因
showModalBottomSheet 弹出的模态框属于独立的路由层级,不在 FlutterMap 的子组件树范围内,因此在模态框内调用 MapController.of(context) 无法找到对应的控制器上下文,从而抛出错误。
解决方案
提前在 FlutterMap 的子组件中获取 MapController 和当前地图缩放级别,直接传递给模态框内的组件,避免在模态框中通过上下文获取。
修改后的完整代码如下:
主FlutterMap部分(无需修改)
FlutterMap( options: const MapOptions( initialCenter: LatLng(54.939196, -3.929788), initialZoom: 14, ), children: [ TileLayer( urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', userAgentPackageName: 'com.example.app', ), const NavigationButton(), ], )
修改NavigationButton:获取控制器并传递给模态框
class NavigationButton extends StatelessWidget { const NavigationButton({super.key}); @override Widget build(BuildContext context) { final mapController = MapController.of(context); final mapCamera = MapCamera.of(context); return Align( alignment: Alignment.bottomLeft, child: Padding( padding: const EdgeInsets.only(left: 2.0, bottom: 2.0, right: 2.0), child: FloatingActionButton( onPressed: () { final currentZoom = mapCamera.zoom; showModalBottomSheet( context: context, builder: (context) => NavigationList( mapController: mapController, currentZoom: currentZoom, ), ); }, child: const Icon(Icons.list), ), ), ); } }
修改NavigationList:接收参数并传递给Shortcut
class NavigationList extends StatelessWidget { final MapController mapController; final double currentZoom; const NavigationList({ super.key, required this.mapController, required this.currentZoom, }); @override Widget build(BuildContext context) { return ListView( children: [ Shortcut( title: "Entrance Hall", lat: 54.949196, lng: -3.929788, mapController: mapController, zoom: currentZoom, ), ], ); } }
修改Shortcut:直接使用传入的控制器和缩放级别
class Shortcut extends StatelessWidget { final String title; final double lat; final double lng; final MapController mapController; final double zoom; const Shortcut({ super.key, required this.title, required this.lat, required this.lng, required this.mapController, required this.zoom, }); @override Widget build(BuildContext context) { return ListTile( title: Text(title), onTap: () { mapController.move(LatLng(lat, lng), zoom); Navigator.pop(context); // 可选:点击后自动关闭模态框 }, ); } }
补充说明
如果项目中有多个组件需要访问MapController,可以考虑使用状态管理工具(如Provider、Riverpod)将控制器全局注入,避免频繁手动传递参数。但针对当前场景,直接传递参数是最简洁高效的方案。
内容的提问来源于stack exchange,提问作者Goofyrocks
相关产品推荐
相关产品推荐

