[android] - decouple style loading from OnMapReady
This commit is contained in:
@@ -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";
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,6 +183,17 @@ public final class MapboxMap {
|
||||
annotationManager.adjustTopOffsetPixels(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@@ -178,6 +206,7 @@ public final class MapboxMap {
|
||||
*/
|
||||
void onFinishLoadingStyle() {
|
||||
locationComponent.onFinishLoadingStyle();
|
||||
locationComponent.onStart();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -622,6 +651,40 @@ public final class MapboxMap {
|
||||
return nativeMapView.getWidth();
|
||||
}
|
||||
|
||||
//
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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) {
|
||||
private final OnStyleLoaded onStyleLoaded;
|
||||
private final Builder builder;
|
||||
private boolean styleLoaded;
|
||||
|
||||
public Style(Builder builder, NativeMapView nativeMapView, OnStyleLoaded styleLoaded) {
|
||||
this.builder = builder;
|
||||
this.nativeMapView = nativeMapView;
|
||||
this.onStyleLoaded = styleLoaded;
|
||||
}
|
||||
|
||||
public void loadStyle(@StyleUrl String styleUrl) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
nativeMapView.setStyleUrl(styleUrl);
|
||||
}
|
||||
|
||||
@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,24 +457,40 @@ 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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
for (Layer layer : layers) {
|
||||
style.addLayer(layer);
|
||||
}
|
||||
|
||||
if (transitionOptions != null) {
|
||||
style.setTransition(transitionOptions);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
public interface OnStyleLoaded {
|
||||
void onStyleLoaded(Style style);
|
||||
}
|
||||
|
||||
//
|
||||
// Style URL constants
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user