google_maps_native_sdk 0.5.0
google_maps_native_sdk: ^0.5.0 copied to clipboard
Native Google Maps plugin for Flutter/FlutterFlow with markers, polylines, caching, events — ideal for mobility apps (e.g., taxi).
Google Maps Native SDK (Flutter/FlutterFlow)
- Native Google Maps plugin (Android Java / iOS Swift) for Flutter, built for mobility apps (e.g., taxi): markers, polylines, events, snapshot and icon caching. Bilingual docs (English/Português) below.
Features
- Native PlatformView (
AndroidView
/UiKitView
). - Markers with icon by URL (memory + disk cache), anchor, rotation and z-index.
- Polylines (points list or encoded polyline via
addPolylineFromEncoded
). - Camera: move/animate, fit bounds with padding.
- Map styling: JSON style or single-color tint via
setMapColor(Color, {dark: false})
. - Extras: traffic, buildings, map padding, snapshot.
- Events: marker tap (
onMarkerTap
stream).
Web (Flutter Web)
- Interactive map powered by Google Maps JavaScript API, loaded dinamically.
- Caching: browser HTTP cache for tiles and marker icons; in-memory reuse for markers/polylines by id; polyline updates in-place.
- Usage: pass
webApiKey
inGoogleMapView
or include the JS script manually inweb/index.html
.
New in 0.3.0 (highlights)
- Map reveal only after map is fully loaded (Android/iOS), with
controller.onMapLoaded
future. - Update polyline points in place:
controller.updatePolylinePoints(id, points)
(no flicker). - URL icons: decode/resize off-main-thread; default anchor now
(0.5, 0.62)
. - Static map helper:
StaticMapView
for lightweight previews and Windows/desktop fallback.
Navigation (Directions + Voice + Follow)
- New: lightweight turn-by-turn helper in Dart. Fetches a Google Directions route, draws the polyline, follows the user's location with camera, and speaks upcoming step instructions.
- API:
MapNavigator.start(controller: ..., options: NavigationOptions(...))
→ returns aNavigationSession
(callstop()
to end).NavigationOptions
requires a Google Directions API key,origin
,destination
; supportsmode
,language
(defaultpt-BR
),voiceGuidance
,cameraZoom
,cameraTilt
,followBearing
,voiceAheadDistanceMeters
, and simple off-route re-route.
- Camera: added
animateCamera(target, {zoom, tilt, bearing, durationMs})
to smoothly follow the user. - Dependencies:
http
,geolocator
,flutter_tts
(already included in this package). Your app must handle location permissions.
Usage (simplified):
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,
),
);
// Later: await session.stop();
Routes API (v2)
RoutesApi.computeRoutes
: alternatives, route modifiers (avoid tolls/highways/ferries), advanced waypoints (sideOfRoad, via/stopover), toll info with estimated price, polyline quality, units/language, configurable FieldMask.RoutesApi.computeRouteMatrix
: compute ETAs for multiple origins/destinations.
Example — compute routes with alternatives and toll info:
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(avoidTolls: false, avoidHighways: true),
alternatives: true,
languageCode: 'pt-BR',
units: Units.metric,
);
for (final r in res.routes) {
await controller.addPolyline(PolylineOptions(id: 'r${r.index}', points: r.points, color: const Color(0xFF1976D2)));
}
Example — route matrix (batch ETAs):
final matrix = await RoutesApi.computeRouteMatrix(
apiKey: 'YOUR_ROUTES_API_KEY',
origins: [Waypoint(location: LatLng(-23.56, -46.65))],
destinations: [Waypoint(location: LatLng(-23.57, -46.66)), Waypoint(location: LatLng(-23.59, -46.67))],
);
Navigation events (feed ETA, distance, instruction):
session.onProgress.listen((p){ /* p.distanceRemainingMeters, p.etaSeconds */ });
session.onInstruction.listen((i){ /* i.text, i.maneuver, i.distanceMeters */ });
session.onState.listen((s){ /* navigating/offRoute/rerouting */ });
session.onSpeedAlert.listen((a){ /* a.overLimit */ });
Install
- Add dependency in your app
pubspec.yaml
(path/git or Pub when published). - Android: add your Google Maps API Key in the app
AndroidManifest.xml
:<meta-data android:name="com.google.android.geo.API_KEY" android:value="YOUR_API_KEY"/>
- iOS: provide the API key in
AppDelegate
or Info.plist:GMSServices.provideAPIKey("YOUR_API_KEY")
orGMSApiKey
in Info.plist.
Quick Start (see example/lib/main.dart
)
- Widget:
GoogleMapView(initialCameraPosition: CameraPosition(target: LatLng(-23.56,-46.65), zoom: 13), onMapCreated: ...)
. - Controller:
addMarker(...)
,addPolyline(...)
,moveCamera(...)
,animateToBounds(...)
,setMapStyle(...)
,setMapColor(...)
,takeSnapshot()
.
Wait for map ready before heavy overlay work:
GoogleMapController? controller;
GoogleMapView(
initialCameraPosition: CameraPosition(target: LatLng(-23.56, -46.65), zoom: 13),
onMapCreated: (c) async {
controller = c;
await c.onMapLoaded; // tiles & style ready
await c.addMarker(MarkerOptions(id: 'a', position: LatLng(-23.56,-46.65)));
},
);
Update an existing polyline without recreate:
await controller!.updatePolylinePoints('route', latestPoints);
Windows/desktop static map (Google Static Maps):
StaticMapView(
apiKey: 'YOUR_API_KEY',
width: 600,
height: 360,
center: LatLng(-23.56, -46.65),
zoom: 13,
polyline: [LatLng(-23.56,-46.65), LatLng(-23.57,-46.66)],
)
Flutter Web usage
GoogleMapView(
webApiKey: 'YOUR_WEB_MAPS_JS_API_KEY', // optional if you add the script in web/index.html
initialCameraPosition: CameraPosition(target: LatLng(-23.56, -46.65), zoom: 13),
onMapCreated: (c) async {
await c.onMapLoaded;
await c.addMarker(MarkerOptions(id: 'w', position: LatLng(-23.56,-46.65)));
},
)
Or add manually to web/index.html
:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_WEB_MAPS_JS_API_KEY&libraries=geometry&v=weekly"></script>
FlutterFlow
- Import as Custom Package and use
GoogleMapView
. UseonMapCreated
to wire controller calls via custom actions.
Best practices (mobility/taxi)
- Enable
trafficEnabled
when useful to reduce visual noise. - Use
setPadding
to accommodate panels (e.g., bottom sheet). - Update driver position with
updateMarker
(optionally smooth in Dart first). - Use URL marker icons; built-in memory+disk cache reduces flicker and network.
- For "snake" live traces: decimate incoming points and throttle updates to ~16–32 ms using
updatePolylinePoints
; avoid removing/adding polylines each frame.
Notes / Limitations
- Location permissions are app responsibility (e.g.,
permission_handler
). - Clustering is not exposed yet (native Utils libs are included for future work).
- Full offline tiles are not supported; use SDK cache + custom tiles if needed.
Routes + TBT Sample
- See
example/lib/routes_tbt_demo.dart
for a complete example that:- Computes alternative routes via Routes API v2 and draws polylines.
- Lets you switch the active route visually.
- Starts turn-by-turn with voice, and listens to
onProgress
,onInstruction
, andonState
streams to drive UI (ETA, next instruction, state).
FlutterFlow Helpers
- In your
onMapCreated
:
GmnsNavHub.setController(controller);
- Compute + draw routes:
await GmnsNavHub.computeRoutesAndDraw(
apiKey: 'YOUR_ROUTES_API_KEY',
origin: LatLng(-23.561, -46.656),
destination: LatLng(-23.570, -46.650),
alternatives: true,
);
- Choose active route:
await GmnsNavHub.chooseActiveRoute(0);
- Start/Stop navigation:
await GmnsNavHub.startNavigation(...)
/await GmnsNavHub.stopNavigation()
- Recenter/Overview:
await GmnsNavHub.recenter()
/await GmnsNavHub.overview()
Android Auto (reference)
- A minimal Car App skeleton is provided at
example/android-auto-sample/README.md
. It shows how to register aCarAppService
with aNavigationTemplate
and wire actions to your Flutter app usingGmnsNavHub
. - FlutterFlow-specific notes in
docs/FLUTTERFLOW_HELPERS.md
.
—