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

Flutter Google Maps无法显示POI及交互功能问题求助

问题描述

使用google_maps_flutter: ^2.7.0实现用户位置标记功能正常,但移动端无法显示周边兴趣点(POI),也无法实现点击POI弹出底部模态框的功能。Web端可正常查看并点击POI,已在AndroidManifest中配置无限制的Google Maps Android API Key,测试在真实设备上进行。终端日志显示Flogger日志过多及FrameEvents错误,但无直接POI相关报错。

解决方案

一、解决POI不显示的问题

  1. 检查地图样式配置
    默认MapType.normal应显示POI,若你自定义了地图样式(mapStyle参数),需确认样式中未隐藏POI元素。无自定义样式则跳过此步。

  2. 升级google_maps_flutter版本
    ^2.7.0版本较旧,存在移动端POI显示的已知问题。建议升级到最新稳定版(如^2.15.0),升级后重新构建项目测试。

  3. 确认API服务启用状态
    登录Google Cloud控制台,确保以下服务已启用:

    • Google Maps Android API
    • Google Maps SDK for iOS
    • 若需实现POI查询,额外启用Places API

二、实现移动端点击POI弹出模态框功能

移动端google_maps_flutter插件未直接提供POI点击回调,需通过Places API配合实现:

步骤1:集成依赖包

在pubspec.yaml中添加依赖:

dependencies:
  google_maps_flutter: ^2.15.0
  google_maps_webservice: ^0.0.20 # 用于调用Places API

步骤2:修改GoogleMapWidget代码

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:google_maps_webservice/places.dart';

// 替换为你的Google Places API Key
const apiKey = "YOUR_PLACES_API_KEY";
final places = GoogleMapsPlaces(apiKey: apiKey);

class GoogleMapWidget extends StatefulWidget {
  final double lat;
  final double lng;
  final String name;
  final String id;
  final dynamic height;
  final bool allRound;
  const GoogleMapWidget({
    super.key,
    required this.lat,
    required this.lng,
    required this.name,
    required this.id,
    required this.height,
    required this.allRound,
  });
  @override
  State<GoogleMapWidget> createState() => _GoogleMapWidgetState();
}

class _GoogleMapWidgetState extends State<GoogleMapWidget> {
  final Completer<GoogleMapController> mapController = Completer();

  @override
  void dispose() {
    mapController.future.then((controller) => controller.dispose());
    super.dispose();
  }

  // 根据坐标查询附近POI
  Future<PlacesSearchResult?> getNearbyPOI(LatLng position) async {
    final response = await places.searchNearbyWithRadius(
      Location(lat: position.latitude, lng: position.longitude),
      50, // 查询半径,单位米,可按需调整
    );

    if (response.status == "OK" && response.results.isNotEmpty) {
      // 返回最近的POI
      return response.results.first;
    }
    return null;
  }

  // 弹出底部模态框展示POI信息
  void showPOIDetails(PlacesSearchResult poi) {
    showModalBottomSheet(
      context: context,
      builder: (context) => Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(poi.name, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
            if (poi.vicinity != null) Text("地址:${poi.vicinity}"),
            if (poi.rating != null) Text("评分:${poi.rating}"),
            // 可添加更多POI信息字段
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    List<Marker> markers = <Marker>[
      Marker(
        markerId: MarkerId(widget.id),
        position: LatLng(widget.lat, widget.lng),
        infoWindow: InfoWindow(title: widget.name),
      )
    ];

    return Container(
      padding: const EdgeInsets.all(10.0),
      decoration: BoxDecoration(
        borderRadius: widget.allRound
            ? BorderRadius.circular(10.0)
            : const BorderRadius.only(topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0)),
        color: Colors.grey[200],
      ),
      child: SizedBox(
        height: widget.height,
        width: MediaQuery.of(context).size.width,
        child: GoogleMap(
          onTap: (LatLng position) async {
            final poi = await getNearbyPOI(position);
            if (poi != null) {
              showPOIDetails(poi);
            }
          },
          initialCameraPosition: CameraPosition(
            target: LatLng(widget.lat, widget.lng),
            zoom: 17.0,
          ),
          mapType: MapType.normal,
          markers: Set<Marker>.of(markers),
          onMapCreated: (GoogleMapController controller) {
            mapController.complete(controller);
          },
        ),
      ),
    );
  }
}

步骤3:配置iOS API Key

在Info.plist中添加:

<key>GoogleMapsAPIKey</key>
<string>YOUR_API_KEY</string>

Android端已配置API Key,无需额外修改。

三、日志问题说明

终端中的Flogger logs和updateAcquireFence错误属于通用日志,与POI显示/点击功能无直接关联,可忽略,不影响核心功能。

内容的提问来源于stack exchange,提问作者AlienDecoy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 08:50:02