🚀 Google Maps Native SDK (Flutter/FlutterFlow)
- Nativo Android (Java) e iOS (Swift) + Flutter, com foco em mobilidade (ex.: táxi): markers, polylines, câmera, estilos, cache de Ãcones, eventos e navegação leve com voz. Bilingue (EN/PT-BR) abaixo.
Highlights
- ðŸ—ºï¸ PlatformView nativo (AndroidView / UiKitView)
- 📠Markers com Ãcone por URL (cache memória+disco), âncora, rotação e z-index
- ➿ Polylines (lista de pontos ou polyline codificado) com update in‑place
- 🎥 Câmera: move/animate, fit bounds com padding
- 🎨 Estilo: JSON ou tint por cor (
setMapColor
) - 🚦 Extras: tráfego, prédios, padding, snapshot
- 🧠Eventos:
onMarkerTap
,onMapLoaded
- 🌠Web: mapa interativo com Google Maps JS (carregamento dinâmico)
- 🧠Routes API v2 + Matriz de ETAs e TBT (voz)
Instalação Rápida
- App Flutter
flutter pub add google_maps_native_sdk
- Android (
AndroidManifest.xml
):<meta-data android:name="com.google.android.geo.API_KEY" android:value="YOUR_API_KEY"/>
- iOS (AppDelegate ou Info.plist):
GMSServices.provideAPIKey("YOUR_API_KEY")
ouGMSApiKey
no Info.plist
- Web
flutter config --enable-web
- Use
GoogleMapView(webApiKey: 'YOUR_WEB_MAPS_JS_API_KEY', ...)
OU adicione emweb/index.html
:<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_WEB_MAPS_JS_API_KEY&libraries=geometry&v=weekly"></script>
Uso Básico
GoogleMapController? controller;
GoogleMapView(
initialCameraPosition: CameraPosition(target: LatLng(-23.56, -46.65), zoom: 13),
trafficEnabled: true,
onMapCreated: (c) async {
controller = c;
await c.onMapLoaded; // ✅ tiles & style prontos
await c.addMarker(MarkerOptions(id: 'a', position: LatLng(-23.56, -46.65), title: 'Hello'));
},
);
Routes API (v2)
RoutesApi.computeRoutes
: alternativas, route modifiers (evitar pedágio/rodovia/balsa), waypoints avançados (sideOfRoad/via), toll info, polyline quality, units/language, FieldMaskRoutesApi.computeRouteMatrix
: ETAs em lote
final res = await RoutesApi.computeRoutes(
apiKey: 'YOUR_ROUTES_API_KEY',
origin: Waypoint(location: LatLng(-23.561, -46.656)),
destination: Waypoint(location: LatLng(-23.570, -46.650)),
intermediates: [Waypoint(location: LatLng(-23.566, -46.653), via: true, sideOfRoad: true)],
modifiers: const RouteModifiers(avoidHighways: true),
alternatives: true,
languageCode: 'pt-BR',
);
for (final r in res.routes) {
await controller!.addPolyline(PolylineOptions(id: 'r${r.index}', points: r.points, color: const Color(0xFF1976D2)));
}
Navegação (TBT + Voz + Follow)
final session = await MapNavigator.start(
controller: controller!,
options: NavigationOptions(
apiKey: 'YOUR_DIRECTIONS_API_KEY',
origin: LatLng(-23.561, -46.656),
destination: LatLng(-23.570, -46.650),
language: 'pt-BR', voiceGuidance: true, ttsRate: 0.95,
),
);
// Alimente sua UI:
session.onProgress.listen((p) {/* ETA e distância restante */});
session.onInstruction.listen((i) {/* texto + manobra */});
session.onState.listen((s) {/* navigating/offRoute/rerouting */});
Flutter Web
GoogleMapView(
webApiKey: 'YOUR_WEB_MAPS_JS_API_KEY', // ou script manual em web/index.html
initialCameraPosition: CameraPosition(
target: LatLng(-23.56, -46.65),
zoom: 13,
tilt: 30, // novo
bearing: 120, // novo
),
onMapCreated: (c) async {
await c.onMapLoaded;
await c.addMarker(MarkerOptions(id: 'w', position: LatLng(-23.56, -46.65)));
},
)
FlutterFlow (Helpers)
- Em
onMapCreated
:GmnsNavHub.setController(controller)
- Ações prontas:
await GmnsNavHub.computeRoutesAndDraw(...)
await GmnsNavHub.chooseActiveRoute(index)
await GmnsNavHub.startNavigation(...) / await GmnsNavHub.stopNavigation()
await GmnsNavHub.recenter()
/await GmnsNavHub.overview()
- Guia dedicado:
docs/FLUTTERFLOW_HELPERS.md
Scripts Úteis (cheat sheet)
- 📦
flutter pub get
— instalar deps - â–¶ï¸
flutter run -d android
— rodar Android - ðŸŽ
flutter run -d ios
— rodar iOS - ðŸŒ
flutter config --enable-web
— habilitar Web - 🧪
flutter run -d chrome
— rodar no Chrome - ðŸ—ï¸
flutter build web --release
— build Web - 🧹
flutter clean
— limpar cache de build
Boas Práticas
- 🔋 Use
onMapLoaded
antes de adicionar overlays pesados - 🠓Snake†realtime: decime pontos +
updatePolylinePoints
(evite remover/adicionar a cada frame) - 🧱
setPadding
para não encobrir UI (bottom sheet, etc.) - 🚘
updateMarker
para mover o driver (suavize no Dart, se quiser)
Notas / Limitações
- 🔒 Permissões de localização são do app (ex.:
permission_handler
) - 🧩 Clustering ainda não exposto
- 📡 Offline completo não suportado (use cache do SDK + tiles custom)
- 🌠Web:
setMyLocationEnabled
é no‑op;takeSnapshot()
não disponÃvel na JS API
Exemplos
example/lib/routes_tbt_demo.dart
— rotas alternativas, troca de rota, TBT + eventos- Android Auto (referência):
example/android-auto-sample/README.md
FAQ
- Web: erro
platformViewRegistry
- Atualize Flutter; este plugin usa o registro padrão de PlatformView no Web
- Conflito com pacote
web
(meu app é só iOS/Android)- O plugin não exige
package:web
no mobile. Rodeflutter clean && flutter pub get
- O plugin não exige
- TTS não fala
- Verifique volume/áudio; em iOS configure AVAudioSession; ajuste
ttsRate/ttsPitch
- Verifique volume/áudio; em iOS configure AVAudioSession; ajuste
— Made with â¤ï¸ for Lucas.
Libraries
- google_maps_native_sdk
- Native Google Maps plugin for Flutter/FlutterFlow.
- google_maps_native_sdk_method_channel
- google_maps_native_sdk_platform_interface
- google_maps_native_sdk_web