You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 09:57:16