IllegalStateException: View size is too small after padding
For Android, I have also tried various solutions and finally found the main reason behind the crash.
The Main Reason behind the crash is Split Screen Support/Multi-Window support in Android 7 - 7.1.2 (API: 24 – 25).
LatLngBounds with padding set based on the percentage of the device width so that it works on small devices. This works even on small devices with 4inch displays, however, it fails in multi-window mode in Android 7.0 and devices that support multi-window mode before that, eg. Galaxy S7.
The solution is to choose the minimum metric between width and height since in Multi-window mode the height can be smaller than the width:
final int width = getResources().getDisplayMetrics().widthPixels;
final int height = getResources().getDisplayMetrics().heightPixels;
final int minMetric = Math.min(width, height);
final int padding = (int) (minMetric * paddingPercentage);
You can choose the padding percentage based on your requirements.
For Move Camera,
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), width, height, padding));
For Animate Camera,
googleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), width, height, padding));
My solution below , works on a map which is roughly 60% of a screen with smaller resolution (1280x720) (code is Kotlin)
val builder = LatLngBounds.Builder()
//storing the MarkerOptions in a hashmap
builder.include(markers[MarkerType.START]?.position)
builder.include(markers[MarkerType.END]?.position)
val bounds = builder.build()
val width = resources.displayMetrics.widthPixels
val height = resources.displayMetrics.heightPixels
val minMetric = min(width, height)
//divide the smallest screen value by 10 , to get a value around 100
val padding = minMetric.div(10)
val cu = CameraUpdateFactory.newLatLngBounds(bounds, padding)
googleMap?.animateCamera(cu)
I have tried a lot of the solution but none of them really solve my problem which was the padding exceeds the actual size of the map.
my solution is to but a small padding and then zoom out to give the same result.
this code is from my app and it works fine for me.
public static void fitThePoints(GoogleMap map, ArrayList<LatLng> points) {
//Calculate the markers to get their position
LatLngBounds.Builder b = new LatLngBounds.Builder();
for (LatLng point : points) b.include(point);
//Change the padding as per needed
map.moveCamera(CameraUpdateFactory.newLatLngBounds(b.build(), ConvertUtils.dp2px(30)));
map.moveCamera(CameraUpdateFactory.zoomTo(map.getCameraPosition().zoom - 0.5f));
}
From the documentation
Do not change the camera with this camera update until the map has undergone layout (in order for this method to correctly determine the appropriate bounding box and zoom level, the map must have a size). Otherwise an IllegalStateException will be thrown. It is NOT sufficient for the map to be available (i.e. getMap() returns a non-null object); the view containing the map must have also undergone layout such that its dimensions have been determined. If you cannot be sure that this has occured, use newLatLngBounds(LatLngBounds, int, int, int) instead and provide the dimensions of the map manually.
Thus, your problem may be that the map doesn't have a size when you are calling mapa.animateCamera(cameraUpdate)
or mapa.moveCamera(cameraUpdate)
.
Anyway, as you say that the exception is being thrown when you rotate your device, I would say that the real issue is that the padding that you are using when calling newLatLngBounds
(ViewUtils.dpAPixeles(MARKERS_DP_OFFSET, contexto)
) is causing problems (maybe the padding is bigger than the View's height / 2?). There is a registered issue (4773) related to Google Maps that may help you solve your problem. As stated there, one possible workaround is to set the cameraUpdate depending on the orientation:
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
cu = CameraUpdateFactory.newLatLngBounds(bounds, ViewUtils.dpAPixeles(MARKERS_DP_OFFSET, contexto));
} else {
// Use another method to get your camera update, for example CameraUpdateFactory.newLatLng(latLng);
}