I'm using the new snapshot() method on the GoogleMap
object, and in my SnapshotReadyCallback I'm swapping out the MapView
in my layout for an ImageView
with the Bitmap
passed to me from the callback. The unfortunate thing about this is, even though I'm getting a Bitmap
it appears that the snapshot was taken before the map finished rendering.
I should also add that this View is being created programmatically, and isn't added to the Activity right away (it's actually being placed in a ScrollView with a bunch of other Views).
The gist of my code (for brevity's sake) is:
public class MyCustomView extends LinearLayout {
private FrameLayout mapContainer;
@Override public void onAttachedToWindow() {
super.onAttachedToWindow();
// Setup GoogleMapOptions ...
mapView = new MapView(getContext(), googleMapOptions);
mapContainer.addView(mapView);
mapView.onCreate(null);
mapView.onResume();
// Setup CameraUpdate ...
mapView.getViewTreeObserver().addOnGlobalLayoutListener(new MapLayoutListener(mapView, cameraUpdate));
}
private class MapLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
private final WeakReference<MapView> mapViewReference;
private final CameraUpdate cameraUpdate;
public MapLayoutListener(MapView mapView, CameraUpdate cameraUpdate) {
mapViewReference = new WeakReference<MapView>(mapView);
this.cameraUpdate = cameraUpdate
}
@Override public void onGlobalLayout() {
MapView mapView = mapViewReference.get();
if (mapView == null) {
return;
}
mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
GoogleMap map = mapView.getMap();
if (map == null) {
return;
}
try {
map.moveCamera(cameraUpdate);
} catch (IllegalStateException e) {
e.printStackTrace();
}
map.snapshot(new GoogleMap.SnapshotReadyCallback() {
@Override public void onSnapshotReady(Bitmap bitmap) {
MapView mapView = mapViewReference.get();
if (mapView == null) {
return;
}
mapContainer.removeAllViews();
ImageView imageView = new ImageView(getContext());
imageView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
imageView.setImageBitmap(bitmap);
mapContainer.addView(imageView);
}
});
}
}
}
Sometimes an IllegalStateException
is thrown when map.moveCamera(cameraUpdate)
is called, complaining that the View has not been laid out yet, but I'm calling it inside the OnGlobalLayoutListener
which I thought was the proper way to get a callback when your View is all done rendering/laying out etc. This exception makes me think otherwise.
So what's the proper way to do this? The docs are scant on details, and the View "lifecycle" isn't very clear. What I need is a callback when the View is ready for me to call snapshot()