I'm making use of the new Android Google Maps API.
I create an activity which includes a MapFragment. In the activity onResume
I set the markers into the GoogleMap object and then define a bounding box for the map which includes all of the markers.
This is using the following pseudo code:
LatLngBounds.Builder builder = new LatLngBounds.Builder();
while(data) {
LatLng latlng = getPosition();
builder.include(latlng);
}
CameraUpdate cameraUpdate = CameraUpdateFactory
.newLatLngBounds(builder.build(), 10);
map.moveCamera(cameraUpdate);
The call to map.moveCamera()
causes my application to crash with the following stack:
Caused by: java.lang.IllegalStateException:
Map size should not be 0. Most likely, layout has not yet
at maps.am.r.b(Unknown Source)
at maps.y.q.a(Unknown Source)
at maps.y.au.a(Unknown Source)
at maps.y.ae.moveCamera(Unknown Source)
at com.google.android.gms.maps.internal.IGoogleMapDelegate$Stub
.onTransact(IGoogleMapDelegate.java:83)
at android.os.Binder.transact(Binder.java:310)
at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a
.moveCamera(Unknown Source)
at com.google.android.gms.maps.GoogleMap.moveCamera(Unknown Source)
at ShowMapActivity.drawMapMarkers(ShowMapActivity.java:91)
at ShowMapActivity.onResume(ShowMapActivity.java:58)
at android.app.Instrumentation
.callActivityOnResume(Instrumentation.java:1185)
at android.app.Activity.performResume(Activity.java:5182)
at android.app.ActivityThread
.performResumeActivity(ActivityThread.java:2732)
If - instead of the newLatLngBounds()
factory method I use newLatLngZoom()
method then the same trap does not occur.
Is the onResume
the best place to draw the markers onto the GoogleMap object or should I be drawing the markers and setting the camera position somewhere else?
The accepted answer wouldn't work for me because I had to use the same code in various places of my app.
Instead of waiting the camera to change, I created a simple solution based on Lee's suggestion of specifying the map size. This is in case your map is the size of the screen.
Hope it helps someone else!
use this it worked for mee
I found this to work and be more simple than the other solutions:
This tries the call again after layout has run. Could probably include a safety to avoid an infinite loop.
As stated in OnCameraChangeListener() is deprecated,
setOnCameraChangeListener
is now deprecated. So you should replace it with one of three mtehods:In my case I used
OnCameraIdleListener
and inside I removed it, because it was invoked again and again on any movement.UPDATE
I removed
googleMap.setOnCameraIdleListener
in my project, because it wasn't called sometimes when a map was shown, but retainedgoogleMap.setOnCameraIdleListener(clusterManager)
.The accepted answer is, as pointed out in the comments, a little hacky. After implementing it I noticed an above-acceptable amount of
IllegalStateException
logs in analytics. The solution I used is to add anOnMapLoadedCallback
in which theCameraUpdate
is performed. The callback is added to theGoogleMap
. After your map fully loads the camera update will be performed.This does cause the map to briefly show the zoomed out (0,0) view before performing the camera update. I feel that this is more acceptable than causing crashes or relying on undocumented behavior though.
If you need to wait for possible user interactions to start, use
OnMapLoadedCallback
as described in the previous answers. But, if all you need is to provide a default location for the map, there is no need for any of the solutions outlined in those answers. BothMapFragment
andMapView
can accept aGoogleMapOptions
at start that can provide the default location all right. The only trick is not to include them directly in your layout because the system will call them without the options then but to initialize them dynamically.Use this in your layout:
and replace the fragment in your
onCreateView()
:Besides being faster to start, there will be no world map shown first and a camera move second. The map will start with the specified location directly.