diff options
author | Tobrun <tobrun.van.nuland@gmail.com> | 2018-11-08 16:27:28 +0100 |
---|---|---|
committer | Tobrun <tobrun@mapbox.com> | 2018-12-10 16:59:50 +0100 |
commit | 4a15a7db79b22843e2a3fce3101ca67a6fda1820 (patch) | |
tree | 5a17932fa8b97fd70d8c02f0d5a780e1d35986e4 /platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox | |
parent | 1cdbb6e06fd6375f7ab79d0e65d6880770433f0c (diff) | |
download | qtlocation-mapboxgl-4a15a7db79b22843e2a3fce3101ca67a6fda1820.tar.gz |
[android] - decouple style loading from OnMapReady
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox')
8 files changed, 252 insertions, 169 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java index afd25f13fc..2c063daa8f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java @@ -117,6 +117,11 @@ public class MapboxConstants { */ public static final String FRAG_ARG_MAPBOXMAPOPTIONS = "MapboxMapOptions"; + /** + * Layer Id of annotations layer + */ + public static final String LAYER_ID_ANNOTATIONS = "com.mapbox.annotations.points"; + // Save instance state keys public static final String STATE_HAS_SAVED_STATE = "mapbox_savedState"; public static final String STATE_CAMERA_POSITION = "mapbox_cameraPosition"; @@ -126,7 +131,6 @@ public class MapboxConstants { public static final String STATE_TILT_ENABLED = "mapbox_tiltEnabled"; public static final String STATE_DOUBLE_TAP_ENABLED = "mapbox_doubleTapEnabled"; public static final String STATE_DEBUG_ACTIVE = "mapbox_debugActive"; - public static final String STATE_STYLE_URL = "mapbox_styleUrl"; public static final String STATE_COMPASS_ENABLED = "mapbox_compassEnabled"; public static final String STATE_COMPASS_GRAVITY = "mapbox_compassGravity"; public static final String STATE_COMPASS_MARGIN_LEFT = "mapbox_compassMarginLeft"; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java index b2f1206d06..aa281ee314 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java @@ -11,7 +11,6 @@ import android.support.annotation.RequiresPermission; import android.support.annotation.StyleRes; import android.support.annotation.VisibleForTesting; import android.view.WindowManager; - import com.mapbox.android.core.location.LocationEngine; import com.mapbox.android.core.location.LocationEngineCallback; import com.mapbox.android.core.location.LocationEngineProvider; @@ -123,7 +122,12 @@ public final class LocationComponent { /** * Indicates whether the component has been initialized. */ - private boolean isInitialized; + private boolean isComponentInitialized; + + /** + * Indicates whether the style has been initialized. + */ + private boolean isStyleInitialized; /** * Indicates that the component is enabled and should be displaying location if Mapbox components are available and @@ -182,7 +186,6 @@ public final class LocationComponent { this.staleStateManager = staleStateManager; this.compassEngine = compassEngine; this.internalLocationEngineProvider = internalLocationEngineProvider; - isInitialized = true; } /** @@ -835,16 +838,17 @@ public final class LocationComponent { * Internal use. */ public void onFinishLoadingStyle() { - if (isInitialized) { + isStyleInitialized = true; + if (isComponentInitialized) { locationLayerController.initializeComponents(options); locationCameraController.initializeOptions(options); + onLocationLayerStart(); } - onLocationLayerStart(); } @SuppressLint("MissingPermission") private void onLocationLayerStart() { - if (!isInitialized || !isComponentStarted) { + if (!isComponentInitialized || !isComponentStarted) { return; } @@ -874,7 +878,7 @@ public final class LocationComponent { } private void onLocationLayerStop() { - if (!isInitialized || !isLayerReady || !isComponentStarted) { + if (!isComponentInitialized || !isLayerReady || !isComponentStarted) { return; } @@ -891,10 +895,10 @@ public final class LocationComponent { } private void initialize(@NonNull Context context, @NonNull LocationComponentOptions options) { - if (isInitialized) { + if (isComponentInitialized) { return; } - isInitialized = true; + isComponentInitialized = true; this.options = options; mapboxMap.addOnMapClickListener(onMapClickListener); @@ -924,6 +928,10 @@ public final class LocationComponent { setRenderMode(RenderMode.NORMAL); setCameraMode(CameraMode.NONE); + if (isStyleInitialized) { + onFinishLoadingStyle(); + } + onLocationLayerStart(); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java index 0e7508ab74..b2ba5e6846 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java @@ -78,7 +78,6 @@ final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsV this.layerSourceProvider = layerSourceProvider; this.bitmapProvider = bitmapProvider; this.locationFeature = featureProvider.generateLocationFeature(locationFeature, options); - initializeComponents(options); setRenderMode(RenderMode.NORMAL); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java index 3b1b87c15f..8e436954c8 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java @@ -12,7 +12,6 @@ import android.support.annotation.Nullable; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Toast; - import com.mapbox.mapboxsdk.MapStrictMode; import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.R; @@ -25,8 +24,8 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Set; import java.util.Locale; +import java.util.Set; /** * Responsible for managing attribution interactions on the map. @@ -180,10 +179,14 @@ public class AttributionDialogManager implements View.OnClickListener, DialogInt List<String> attributions = new ArrayList<>(); String attribution; - for (Source source : mapboxMap.getStyle().getSources()) { - attribution = source.getAttribution(); - if (!attribution.isEmpty()) { - attributions.add(source.getAttribution()); + + Style style = mapboxMap.getStyle(); + if (style != null) { + for (Source source : mapboxMap.getStyle().getSources()) { + attribution = source.getAttribution(); + if (!attribution.isEmpty()) { + attributions.add(source.getAttribution()); + } } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index 8e76d14fc3..8ec5a923bf 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -25,8 +25,6 @@ import com.mapbox.mapboxsdk.MapStrictMode; import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.annotations.Annotation; -import com.mapbox.mapboxsdk.camera.CameraPosition; -import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.location.LocationComponent; import com.mapbox.mapboxsdk.maps.renderer.MapRenderer; @@ -34,7 +32,6 @@ import com.mapbox.mapboxsdk.maps.renderer.glsurfaceview.GLSurfaceViewMapRenderer import com.mapbox.mapboxsdk.maps.renderer.textureview.TextureViewMapRenderer; import com.mapbox.mapboxsdk.maps.widgets.CompassView; import com.mapbox.mapboxsdk.net.ConnectivityReceiver; -import com.mapbox.mapboxsdk.offline.OfflineRegionDefinition; import com.mapbox.mapboxsdk.storage.FileSource; import com.mapbox.mapboxsdk.utils.BitmapUtils; @@ -484,69 +481,6 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { } } - /** - * <p> - * Loads a new map style from the specified URL. - * </p> - * {@code url} can take the following forms: - * <ul> - * <li>{@code Style.*}: load one of the bundled styles in {@link Style}.</li> - * <li>{@code mapbox://styles/<user>/<style>}: - * retrieves the style from a <a href="https://www.mapbox.com/account/">Mapbox account.</a> - * {@code user} is your username. {@code style} is the ID of your custom - * style created in <a href="https://www.mapbox.com/studio">Mapbox Studio</a>.</li> - * <li>{@code http://...} or {@code https://...}: - * retrieves the style over the Internet from any web server.</li> - * <li>{@code asset://...}: - * reads the style from the APK {@code assets/} directory. - * This is used to load a style bundled with your app.</li> - * <li>{@code null}: loads the default {@link Style#MAPBOX_STREETS} style.</li> - * </ul> - * <p> - * This method is asynchronous and will return immediately before the style finishes loading. - * If you wish to wait for the map to finish loading listen to {@link OnDidFinishLoadingStyleListener} callback. - * </p> - * If the style fails to load or an invalid style URL is set, the map view will become blank. - * An error message will be logged in the Android logcat and provided to the {@link OnDidFailLoadingMapListener} - * callback. - * - * @param url The URL of the map style - * @see Style - */ - public void setStyleUrl(@NonNull String url) { - if (nativeMapView != null) { - // null-checking the nativeMapView as it can be mistakenly called after it's been destroyed - nativeMapView.setStyleUrl(url); - } - } - - /** - * Loads a new style from the specified offline region definition and moves the map camera to that region. - * - * @param definition the offline region definition - * @see OfflineRegionDefinition - */ - public void setOfflineRegionDefinition(@NonNull OfflineRegionDefinition definition) { - double minZoom = definition.getMinZoom(); - double maxZoom = definition.getMaxZoom(); - - CameraPosition cameraPosition = new CameraPosition.Builder() - .target(definition.getBounds().getCenter()) - .zoom(minZoom) - .build(); - setStyleUrl(definition.getStyleURL()); - - if (mapboxMap == null) { - mapboxMapOptions.camera(cameraPosition); - mapboxMapOptions.minZoomPreference(minZoom); - mapboxMapOptions.maxZoomPreference(maxZoom); - } else { - mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); - mapboxMap.setMinZoomPreference(minZoom); - mapboxMap.setMaxZoomPreference(maxZoom); - } - } - // // Rendering // @@ -971,7 +905,7 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { */ @UiThread public void getMapAsync(final @NonNull OnMapReadyCallback callback) { - if (mapCallback.isInitialLoad() || mapboxMap == null) { + if (mapboxMap == null) { // Add callback to the list only if the style hasn't loaded, or the drawing surface isn't ready mapCallback.addOnMapReadyCallback(callback); } else { @@ -1013,34 +947,24 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { * The initial render callback waits for rendering to happen before making the map visible for end-users. * We wait for the second DID_FINISH_RENDERING_FRAME map change event as the first will still show a black surface. */ - private class InitialRenderCallback implements OnDidFinishLoadingStyleListener, OnDidFinishRenderingFrameListener { + private class InitialRenderCallback implements OnDidFinishRenderingFrameListener { private int renderCount; - private boolean styleLoaded; InitialRenderCallback() { - addOnDidFinishLoadingStyleListener(this); addOnDidFinishRenderingFrameListener(this); } @Override - public void onDidFinishLoadingStyle() { - styleLoaded = true; - } - - @Override public void onDidFinishRenderingFrame(boolean fully) { - if (styleLoaded) { - renderCount++; - if (renderCount == 2) { - MapView.this.setForeground(null); - removeOnDidFinishRenderingFrameListener(this); - } + renderCount++; + if (renderCount == 2) { + MapView.this.setForeground(null); + removeOnDidFinishRenderingFrameListener(this); } } private void onDestroy() { - removeOnDidFinishLoadingStyleListener(this); removeOnDidFinishRenderingFrameListener(this); } } @@ -1140,7 +1064,6 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { OnCameraIsChangingListener, OnCameraDidChangeListener { private final List<OnMapReadyCallback> onMapReadyCallbackList = new ArrayList<>(); - private boolean initialLoad = true; MapCallback() { addOnWillStartLoadingMapListener(this); @@ -1152,11 +1075,9 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { } void initialised() { - if (!initialLoad) { - // Style has loaded before the drawing surface has been initialized, delivering OnMapReady - mapboxMap.onPreMapReady(); - onMapReady(); - } + mapboxMap.onPreMapReady(); + onMapReady(); + mapboxMap.onPostMapReady(); } /** @@ -1176,10 +1097,6 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { } } - boolean isInitialLoad() { - return initialLoad; - } - void addOnMapReadyCallback(OnMapReadyCallback callback) { onMapReadyCallbackList.add(callback); } @@ -1196,7 +1113,7 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { @Override public void onWillStartLoadingMap() { - if (mapboxMap != null && !initialLoad) { + if (mapboxMap != null) { mapboxMap.onStartLoadingMap(); } } @@ -1204,15 +1121,8 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { @Override public void onDidFinishLoadingStyle() { if (mapboxMap != null) { - if (initialLoad) { - initialLoad = false; - mapboxMap.onPreMapReady(); - onMapReady(); - } else { - mapboxMap.onFinishLoadingStyle(); - } + mapboxMap.onFinishLoadingStyle(); } - initialLoad = false; } @Override diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index aafa033791..6a95338db7 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -12,7 +12,6 @@ import android.support.annotation.Size; import android.support.annotation.UiThread; import android.text.TextUtils; import android.view.View; - import com.mapbox.android.gestures.AndroidGesturesManager; import com.mapbox.android.gestures.MoveGestureDetector; import com.mapbox.android.gestures.RotateGestureDetector; @@ -36,8 +35,10 @@ import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.location.LocationComponent; import com.mapbox.mapboxsdk.log.Logger; +import com.mapbox.mapboxsdk.offline.OfflineRegionDefinition; import com.mapbox.mapboxsdk.style.expressions.Expression; +import java.util.ArrayList; import java.util.List; /** @@ -68,13 +69,15 @@ public final class MapboxMap { @Nullable private MapboxMap.OnFpsChangedListener onFpsChangedListener; + private List<Style.OnStyleLoaded> styleLoadedCallbacks = new ArrayList<>(); + + @Nullable private Style style; MapboxMap(NativeMapView map, Transform transform, UiSettings ui, Projection projection, OnGesturesManagerInteractionListener listener, AnnotationManager annotations, CameraChangeDispatcher cameraChangeDispatcher) { this.nativeMapView = map; - this.style = new Style(nativeMapView); this.uiSettings = ui; this.projection = projection; this.annotationManager = annotations.bind(this); @@ -95,6 +98,26 @@ public final class MapboxMap { setPrefetchesTiles(options); } + /** + * Get the Style of the map asynchronously. + */ + public void getStyle(@NonNull Style.OnStyleLoaded onStyleLoaded) { + if (style == null) { + styleLoadedCallbacks.add(onStyleLoaded); + } else { + onStyleLoaded.onStyleLoaded(style); + } + } + + /** + * Get the Style of the map. + * <p> + * Returns null when style is being loaded. + * </p> + * + * @return the style of the map + */ + @Nullable public Style getStyle() { return style; } @@ -122,7 +145,6 @@ public final class MapboxMap { void onSaveInstanceState(@NonNull Bundle outState) { outState.putParcelable(MapboxConstants.STATE_CAMERA_POSITION, transform.getCameraPosition()); outState.putBoolean(MapboxConstants.STATE_DEBUG_ACTIVE, nativeMapView.getDebug()); - outState.putString(MapboxConstants.STATE_STYLE_URL, nativeMapView.getStyleUrl()); uiSettings.onSaveInstanceState(outState); } @@ -143,11 +165,6 @@ public final class MapboxMap { } nativeMapView.setDebug(savedInstanceState.getBoolean(MapboxConstants.STATE_DEBUG_ACTIVE)); - - final String styleUrl = savedInstanceState.getString(MapboxConstants.STATE_STYLE_URL); - if (!TextUtils.isEmpty(styleUrl)) { - nativeMapView.setStyleUrl(savedInstanceState.getString(MapboxConstants.STATE_STYLE_URL)); - } } /** @@ -167,6 +184,17 @@ public final class MapboxMap { } /** + * Called when the OnMapReadyCallback has finished executing. + * <p> + * Invalidation of the camera position is required to update the added components in + * OnMapReadyCallback with the correct transformation. + * </p> + */ + void onPostMapReady() { + transform.invalidateCameraPosition(); + } + + /** * Called when the map will start loading style. */ void onStartLoadingMap() { @@ -178,6 +206,7 @@ public final class MapboxMap { */ void onFinishLoadingStyle() { locationComponent.onFinishLoadingStyle(); + locationComponent.onStart(); } /** @@ -623,6 +652,40 @@ public final class MapboxMap { } // + // Offline + // + + /** + * Loads a new style from the specified offline region definition and moves the map camera to that region. + * + * @param definition the offline region definition + * @see OfflineRegionDefinition + */ + public void setOfflineRegionDefinition(@NonNull OfflineRegionDefinition definition) { + setOfflineRegionDefinition(definition, null); + } + + /** + * Loads a new style from the specified offline region definition and moves the map camera to that region. + * + * @param definition the offline region definition + * @see OfflineRegionDefinition + */ + public void setOfflineRegionDefinition(@NonNull OfflineRegionDefinition definition, + @Nullable Style.OnStyleLoaded callback) { + double minZoom = definition.getMinZoom(); + double maxZoom = definition.getMaxZoom(); + CameraPosition cameraPosition = new CameraPosition.Builder() + .target(definition.getBounds().getCenter()) + .zoom(minZoom) + .build(); + moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); + setMinZoomPreference(minZoom); + setMaxZoomPreference(maxZoom); + setStyle(new Style.Builder().fromUrl(definition.getStyleURL()), callback); + } + + // // Debug // @@ -675,8 +738,31 @@ public final class MapboxMap { // Styling // - public Style setStyle(Style.Builder builder) { - return style = builder.build(nativeMapView); + public void setStyle(@Style.StyleUrl String style) { + this.setStyle(style, null); + } + + public void setStyle(@Style.StyleUrl String style, final Style.OnStyleLoaded callback) { + this.setStyle(new Style.Builder().fromUrl(style), callback); + } + + public void setStyle(Style.Builder builder) { + this.setStyle(builder, null); + } + + public void setStyle(Style.Builder builder, final Style.OnStyleLoaded callback) { + builder.build(nativeMapView, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(Style style) { + MapboxMap.this.style = style; + if (callback != null) { + callback.onStyleLoaded(style); + } + for (Style.OnStyleLoaded styleLoadedCallback : styleLoadedCallbacks) { + styleLoadedCallback.onStyleLoaded(style); + } + } + }); } /** @@ -687,14 +773,14 @@ public final class MapboxMap { private void setStyleUrl(@NonNull MapboxMapOptions options) { String style = options.getStyleUrl(); if (!TextUtils.isEmpty(style)) { - setStyle(new Style.Builder().withStyleUrl(style)); + setStyle(new Style.Builder().fromUrl(style)); } } private void setStyleJson(@NonNull MapboxMapOptions options) { String styleJson = options.getStyleJson(); if (!TextUtils.isEmpty(styleJson)) { - setStyle(new Style.Builder().withStyleJson(styleJson)); + setStyle(new Style.Builder().fromJson(styleJson)); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index 0f5d4de5ab..c3003f2d0c 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -71,6 +71,8 @@ final class NativeMapView { // Flag to indicating destroy was called private boolean destroyed = false; + private Style style; + // Holds the pointer to JNI NativeMapView @Keep long nativePtr = 0; @@ -186,9 +188,10 @@ final class NativeMapView { nativeSetStyleUrl(url); } + @NonNull public String getStyleUrl() { if (checkState("getStyleUrl")) { - return null; + return ""; } return nativeGetStyleUrl(); } @@ -200,9 +203,10 @@ final class NativeMapView { nativeSetStyleJson(newStyleJson); } + @NonNull public String getStyleJson() { if (checkState("getStyleJson")) { - return null; + return ""; } return nativeGetStyleJson(); } @@ -933,6 +937,9 @@ final class NativeMapView { @Keep private void onWillStartLoadingMap() { stateCallback.onWillStartLoadingMap(); + if (style != null) { + style.onWillStartLoadingStyle(); + } } @Keep @@ -967,6 +974,7 @@ final class NativeMapView { @Keep private void onDidFinishLoadingStyle() { + style.onDidFinishLoadingStyle(); stateCallback.onDidFinishLoadingStyle(); } @@ -1331,6 +1339,11 @@ final class NativeMapView { }); } + // TODO remove dependency of Style on NativeMapView + public void setStyle(Style style) { + this.style = style; + } + // // Image conversion // diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Style.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Style.java index edbb2764cd..7ae04d2a86 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Style.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Style.java @@ -5,6 +5,7 @@ import android.support.annotation.IntRange; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.StringDef; +import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.layers.TransitionOptions; import com.mapbox.mapboxsdk.style.light.Light; @@ -15,6 +16,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; public class Style { @@ -22,35 +24,23 @@ public class Style { private final HashMap<String, Source> sources = new HashMap<>(); private final HashMap<String, Layer> layers = new HashMap<>(); - public Style(NativeMapView nativeMapView) { - this.nativeMapView = nativeMapView; - } - - public void loadStyle(@StyleUrl String styleUrl) { - for (Source source : sources.values()) { - if (source != null) { - source.setDetached(); - nativeMapView.removeSource(source); - } - } + private final OnStyleLoaded onStyleLoaded; + private final Builder builder; + private boolean styleLoaded; - for (Layer layer : layers.values()) { - if (layer != null) { - layer.setDetached(); - nativeMapView.removeLayer(layer); - } - } - - nativeMapView.setStyleUrl(styleUrl); + public Style(Builder builder, NativeMapView nativeMapView, OnStyleLoaded styleLoaded) { + this.builder = builder; + this.nativeMapView = nativeMapView; + this.onStyleLoaded = styleLoaded; } - @Nullable - public String getUrl(){ + @NonNull + public String getUrl() { return nativeMapView.getStyleUrl(); } - @Nullable - public String getJson(){ + @NonNull + public String getJson() { return nativeMapView.getStyleJson(); } @@ -336,6 +326,59 @@ public class Style { return nativeMapView.getLight(); } + + /** + * Called when the underlying map will start loading a new style. This method will clean up this style + * by setting the java sources and layers in a detached state and removing them from core. + */ + public void onWillStartLoadingStyle() { + for (Source source : sources.values()) { + if (source != null) { + source.setDetached(); + nativeMapView.removeSource(source); + } + } + + for (Layer layer : layers.values()) { + if (layer != null) { + layer.setDetached(); + nativeMapView.removeLayer(layer); + } + } + + sources.clear(); + layers.clear(); + } + + /** + * Called when the underlying map has finished loading this style. + * This method will add all components added to the builder that were defined with the 'with' prefix. + */ + public void onDidFinishLoadingStyle() { + if (!styleLoaded) { + styleLoaded = true; + for (Source source : builder.sources) { + addSource(source); + } + + for (Layer layer : builder.layers) { + addLayerBelow(layer, MapboxConstants.LAYER_ID_ANNOTATIONS); + } + + for (Map.Entry<String, Bitmap> stringBitmapEntry : builder.images.entrySet()) { + addImage(stringBitmapEntry.getKey(), stringBitmapEntry.getValue()); + } + + if (builder.transitionOptions != null) { + setTransition(builder.transitionOptions); + } + + if (onStyleLoaded != null) { + onStyleLoaded.onStyleLoaded(this); + } + } + } + // // Builder // @@ -347,9 +390,9 @@ public class Style { private List<Source> sources = new ArrayList<>(); // TODO allow adding below and at index private List<Layer> layers = new ArrayList<>(); + private HashMap<String, Bitmap> images = new HashMap<>(); private TransitionOptions transitionOptions; - /** * <p> * Loads a new map style asynchronous from the specified URL. @@ -380,8 +423,8 @@ public class Style { * @param url The URL of the map style * @see Style */ - public Builder withStyleUrl(@StyleUrl String url) { - this.styleUrl = styleUrl; + public Builder fromUrl(String url) { + this.styleUrl = url; return this; } @@ -393,7 +436,7 @@ public class Style { * will be triggered. * </p> */ - public Builder withStyleJson(String styleJson) { + public Builder fromJson(String styleJson) { this.styleJson = styleJson; return this; } @@ -403,6 +446,7 @@ public class Style { return this; } + // TODO add layer at support! public Builder withLayer(Layer layer) { layers.add(layer); return this; @@ -413,25 +457,41 @@ public class Style { return this; } - Style build(NativeMapView nativeMapView) { - Style style = new Style(nativeMapView); - for (Source source : sources) { - style.addSource(source); - } + // TODO add SDF support! + public Builder withImage(String name, Bitmap image) { + images.put(name, image); + return this; + } - for (Layer layer : layers) { - style.addLayer(layer); + Style build(NativeMapView nativeMapView, OnStyleLoaded styleLoaded) { + Style style = new Style(this, nativeMapView, styleLoaded); + nativeMapView.setStyle(style); + + if (styleUrl != null) { + nativeMapView.setStyleUrl(styleUrl); + } else if (styleJson != null) { + nativeMapView.setStyleJson(styleJson); + } else { + // user didn't provide a `from` component, + // flag the style as loaded, + // add components defined added using the `with` prefix. + style.onDidFinishLoadingStyle(); } - if (transitionOptions != null) { - style.setTransition(transitionOptions); - } return style; } } // + // + // + + public interface OnStyleLoaded { + void onStyleLoaded(Style style); + } + + // // Style URL constants // |