MapView v2 snapshot() creates an unfinished Bitmap

2019-05-26 17:56发布

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()

0条回答
登录 后发表回答