Use case
Apps that place panels, sheets, or sidebars over the map (e.g., a details card on the left, a bottom sheet on mobile) need to set asymmetric GoogleMap(padding: EdgeInsets) so Google Maps knows where the "visible area" is. When a marker is selected, the camera needs to recenter within that padded visible area.
Currently, changing the widget-level padding and calling animateCamera are two independent operations with no coordination. This causes competing animations when the padding changes at the same time as the camera needs to recenter:
- Padding changes → Google Maps shifts the viewport (visible jump)
animateCamera fires → but may use stale padding for its target calculation, causing the camera to wobble or reverse direction mid-animation
The workaround is to set the padding instantly (causing a visible viewport jump), wait a frame for Maps to process it, then call animateCamera. This works but produces a noticeable two-step motion rather than one smooth animation.
Proposal
Add an EdgeInsets parameter to CameraUpdate.newLatLngBounds:
// Current API - only uniform padding
static CameraUpdate newLatLngBounds(LatLngBounds bounds, double padding)
// Proposed addition - asymmetric padding
static CameraUpdate newLatLngBoundsWithEdgeInsets(LatLngBounds bounds, EdgeInsets padding)
This would allow the camera update to atomically calculate the target position using the specified asymmetric padding, rather than relying on the widget-level padding being set and processed first.
Native SDK evidence
iOS ✅ Already supported
The iOS Google Maps SDK already provides GMSCameraUpdate.fitBounds(_:withEdgeInsets:) which accepts UIEdgeInsets with individual top/left/bottom/right values:
GMSCameraUpdate *update = [GMSCameraUpdate fitBounds:bounds withEdgeInsets:UIEdgeInsetsMake(top, left, bottom, right)];
[mapView animateWithCameraUpdate:update];
This is a direct 1:1 mapping. The Flutter plugin simply isn't exposing this existing native capability.
Reference: GMSCameraUpdate Class Reference
Web ✅ Already supported
The Google Maps JavaScript API's fitBounds method accepts a padding parameter with individual top, right, bottom, left values:
map.fitBounds(bounds, { top: 80, right: 16, bottom: 350, left: 16 });
This is a direct mapping via the google_maps Dart package's gmaps.Padding object.
Android ⚠️ No direct equivalent
Android's CameraUpdateFactory.newLatLngBounds(LatLngBounds, int) only accepts uniform padding. Unlike iOS and Web, there is no newLatLngBounds variant that accepts asymmetric edge insets.
Note: GoogleMap.setPadding(int left, int top, int right, int bottom) is not a viable workaround here — it serves a fundamentally different purpose. setPadding defines the map's "usable area", permanently repositioning the Google logo, legal text, compass, and zoom controls. It should not be temporarily mutated to simulate per-camera-update insets.
Possible approaches for Android:
-
Manual camera calculation — The Flutter Android plugin could compute the target CameraPosition (center + zoom) by taking the bounds, the requested edge insets, and the current viewport dimensions, effectively reimplementing what iOS's fitBounds:withEdgeInsets: does natively. This is self-contained and shippable without upstream changes.
-
Upstream SDK feature request — File a feature request on the Google Maps Platform issue tracker for a CameraUpdateFactory.newLatLngBounds(LatLngBounds, int, int, int, int) overload, bringing Android to parity with iOS. This would allow a clean 1:1 mapping but is dependent on Google's prioritisation.
Current Flutter plugin version
google_maps_flutter: 2.14.2
Use case
Apps that place panels, sheets, or sidebars over the map (e.g., a details card on the left, a bottom sheet on mobile) need to set asymmetric
GoogleMap(padding: EdgeInsets)so Google Maps knows where the "visible area" is. When a marker is selected, the camera needs to recenter within that padded visible area.Currently, changing the widget-level
paddingand callinganimateCameraare two independent operations with no coordination. This causes competing animations when the padding changes at the same time as the camera needs to recenter:animateCamerafires → but may use stale padding for its target calculation, causing the camera to wobble or reverse direction mid-animationThe workaround is to set the padding instantly (causing a visible viewport jump), wait a frame for Maps to process it, then call
animateCamera. This works but produces a noticeable two-step motion rather than one smooth animation.Proposal
Add an
EdgeInsetsparameter toCameraUpdate.newLatLngBounds:This would allow the camera update to atomically calculate the target position using the specified asymmetric padding, rather than relying on the widget-level padding being set and processed first.
Native SDK evidence
iOS ✅ Already supported
The iOS Google Maps SDK already provides
GMSCameraUpdate.fitBounds(_:withEdgeInsets:)which acceptsUIEdgeInsetswith individual top/left/bottom/right values:This is a direct 1:1 mapping. The Flutter plugin simply isn't exposing this existing native capability.
Reference: GMSCameraUpdate Class Reference
Web ✅ Already supported
The Google Maps JavaScript API's
fitBoundsmethod accepts apaddingparameter with individualtop,right,bottom,leftvalues:This is a direct mapping via the
google_mapsDart package'sgmaps.Paddingobject.Android⚠️ No direct equivalent
Android's
CameraUpdateFactory.newLatLngBounds(LatLngBounds, int)only accepts uniform padding. Unlike iOS and Web, there is nonewLatLngBoundsvariant that accepts asymmetric edge insets.Possible approaches for Android:
Manual camera calculation — The Flutter Android plugin could compute the target
CameraPosition(center + zoom) by taking the bounds, the requested edge insets, and the current viewport dimensions, effectively reimplementing what iOS'sfitBounds:withEdgeInsets:does natively. This is self-contained and shippable without upstream changes.Upstream SDK feature request — File a feature request on the Google Maps Platform issue tracker for a
CameraUpdateFactory.newLatLngBounds(LatLngBounds, int, int, int, int)overload, bringing Android to parity with iOS. This would allow a clean 1:1 mapping but is dependent on Google's prioritisation.Current Flutter plugin version
google_maps_flutter: 2.14.2