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 (
onMarkerTapstream).
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
webApiKeyinGoogleMapViewor 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.onMapLoadedfuture. - 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:
StaticMapViewfor 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).NavigationOptionsrequires 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
AppDelegateor Info.plist:GMSServices.provideAPIKey("YOUR_API_KEY")orGMSApiKeyin 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. UseonMapCreatedto wire controller calls via custom actions.
Best practices (mobility/taxi)
- Enable
trafficEnabledwhen useful to reduce visual noise. - Use
setPaddingto 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.dartfor 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, andonStatestreams 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 aCarAppServicewith aNavigationTemplateand wire actions to your Flutter app usingGmnsNavHub. - FlutterFlow-specific notes in
docs/FLUTTERFLOW_HELPERS.md.
—