diff options
3 files changed, 146 insertions, 18 deletions
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 73ecf44d41..c97713cfb5 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 @@ -73,6 +73,9 @@ final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsV private boolean isHidden = true; + @Nullable + private String layerBelow; + LocationLayerController(MapboxMap mapboxMap, Style style, LayerSourceProvider layerSourceProvider, LayerFeatureProvider featureProvider, LayerBitmapProvider bitmapProvider, @NonNull LocationComponentOptions options) { @@ -99,6 +102,14 @@ final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsV } void applyStyle(@NonNull LocationComponentOptions options) { + String newLayerBelowOption = options.layerBelow(); + if ((layerBelow != null || newLayerBelowOption != null)) { + if (layerBelow == null || !layerBelow.equals(newLayerBelowOption)) { + removeLayers(); + addLayers(newLayerBelowOption); + } + } + this.options = options; float elevation = options.elevation(); @@ -211,6 +222,7 @@ final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsV } private void addLayers(@NonNull String idBelowLayer) { + layerBelow = idBelowLayer; addSymbolLayer(BEARING_LAYER, idBelowLayer); addSymbolLayer(FOREGROUND_LAYER, BEARING_LAYER); addSymbolLayer(BACKGROUND_LAYER, FOREGROUND_LAYER); @@ -233,6 +245,13 @@ final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsV layerMap.add(layer.getId()); } + private void removeLayers() { + for (String layerId : layerMap) { + style.removeLayer(layerId); + } + layerMap.clear(); + } + private void setBearingProperty(@NonNull String propertyId, float bearing) { locationFeature.addNumberProperty(propertyId, bearing); refreshSource(); diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.java index 68e31275f1..e105909c8c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.java +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationLayerControllerTest.java @@ -14,7 +14,9 @@ import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; +import static com.mapbox.mapboxsdk.location.LocationComponentConstants.ACCURACY_LAYER; import static com.mapbox.mapboxsdk.location.LocationComponentConstants.BACKGROUND_ICON; import static com.mapbox.mapboxsdk.location.LocationComponentConstants.BACKGROUND_LAYER; import static com.mapbox.mapboxsdk.location.LocationComponentConstants.BACKGROUND_STALE_ICON; @@ -273,6 +275,109 @@ public class LocationLayerControllerTest { } @Test + public void applyStyle_layerBelowChanged() { + LayerSourceProvider sourceProvider = buildLayerProvider(); + when(sourceProvider.generateSource(any(Feature.class))).thenReturn(mock(GeoJsonSource.class)); + + Layer bearingLayer = mock(Layer.class); + when(bearingLayer.getId()).thenReturn(BEARING_LAYER); + when(sourceProvider.generateLayer(BEARING_LAYER)).thenReturn(bearingLayer); + Layer foregroundLayer = mock(Layer.class); + when(foregroundLayer.getId()).thenReturn(FOREGROUND_LAYER); + when(sourceProvider.generateLayer(FOREGROUND_LAYER)).thenReturn(foregroundLayer); + Layer backgroundLayer = mock(Layer.class); + when(backgroundLayer.getId()).thenReturn(BACKGROUND_LAYER); + when(sourceProvider.generateLayer(BACKGROUND_LAYER)).thenReturn(backgroundLayer); + Layer shadowLayer = mock(Layer.class); + when(shadowLayer.getId()).thenReturn(SHADOW_LAYER); + when(sourceProvider.generateLayer(SHADOW_LAYER)).thenReturn(shadowLayer); + Layer accuracyLayer = mock(Layer.class); + when(accuracyLayer.getId()).thenReturn(ACCURACY_LAYER); + when(sourceProvider.generateAccuracyLayer()).thenReturn(accuracyLayer); + + LocationComponentOptions options = mock(LocationComponentOptions.class); + LayerBitmapProvider bitmapProvider = mock(LayerBitmapProvider.class); + Bitmap bitmap = mock(Bitmap.class); + when(bitmapProvider.generateShadowBitmap(any(LocationComponentOptions.class))).thenReturn(bitmap); + + LocationLayerController layerController = + new LocationLayerController(mapboxMap, mapboxMap.getStyle(), sourceProvider, buildFeatureProvider(options), + bitmapProvider, options); + + Layer bearingLayer2 = mock(Layer.class); + when(sourceProvider.generateLayer(BEARING_LAYER)).thenReturn(bearingLayer2); + Layer foregroundLayer2 = mock(Layer.class); + when(sourceProvider.generateLayer(FOREGROUND_LAYER)).thenReturn(foregroundLayer2); + Layer backgroundLayer2 = mock(Layer.class); + when(sourceProvider.generateLayer(BACKGROUND_LAYER)).thenReturn(backgroundLayer2); + Layer shadowLayer2 = mock(Layer.class); + when(sourceProvider.generateLayer(SHADOW_LAYER)).thenReturn(shadowLayer2); + Layer accuracyLayer2 = mock(Layer.class); + when(sourceProvider.generateAccuracyLayer()).thenReturn(accuracyLayer2); + String layerBelow = "layer-below"; + when(options.layerBelow()).thenReturn(layerBelow); + + layerController.applyStyle(options); + + verify(style).removeLayer(BEARING_LAYER); + verify(style).removeLayer(FOREGROUND_LAYER); + verify(style).removeLayer(BACKGROUND_LAYER); + verify(style).removeLayer(SHADOW_LAYER); + verify(style).removeLayer(ACCURACY_LAYER); + + verify(style).addLayerBelow(bearingLayer2, layerBelow); + verify(style).addLayerBelow(foregroundLayer2, BEARING_LAYER); + verify(style).addLayerBelow(backgroundLayer2, FOREGROUND_LAYER); + verify(style).addLayerBelow(shadowLayer2, BACKGROUND_LAYER); + verify(style).addLayerBelow(accuracyLayer2, BACKGROUND_LAYER); + } + + @Test + public void applyStyle_layerBelowNotChanged() { + LayerSourceProvider sourceProvider = buildLayerProvider(); + when(sourceProvider.generateSource(any(Feature.class))).thenReturn(mock(GeoJsonSource.class)); + LocationComponentOptions options = mock(LocationComponentOptions.class); + LayerBitmapProvider bitmapProvider = mock(LayerBitmapProvider.class); + Bitmap bitmap = mock(Bitmap.class); + when(bitmapProvider.generateShadowBitmap(any(LocationComponentOptions.class))).thenReturn(bitmap); + + String layerBelow = "layer-below"; + when(options.layerBelow()).thenReturn(layerBelow); + + LocationLayerController layerController = + new LocationLayerController(mapboxMap, mapboxMap.getStyle(), sourceProvider, buildFeatureProvider(options), + bitmapProvider, options); + + options = mock(LocationComponentOptions.class); + layerBelow = "layer-below"; + when(options.layerBelow()).thenReturn(layerBelow); + layerController.applyStyle(options); + + verify(style, times(0)).removeLayer(any(String.class)); + verify(style, times(5)).addLayerBelow(any(Layer.class), any(String.class)); + } + + @Test + public void applyStyle_layerBelowNotChangedNull() { + LayerSourceProvider sourceProvider = buildLayerProvider(); + when(sourceProvider.generateSource(any(Feature.class))).thenReturn(mock(GeoJsonSource.class)); + LocationComponentOptions options = mock(LocationComponentOptions.class); + LayerBitmapProvider bitmapProvider = mock(LayerBitmapProvider.class); + Bitmap bitmap = mock(Bitmap.class); + when(bitmapProvider.generateShadowBitmap(any(LocationComponentOptions.class))).thenReturn(bitmap); + + LocationLayerController layerController = + new LocationLayerController(mapboxMap, mapboxMap.getStyle(), sourceProvider, buildFeatureProvider(options), + bitmapProvider, options); + + options = mock(LocationComponentOptions.class); + layerController.applyStyle(options); + + verify(style, times(0)).removeLayer(any(String.class)); + verify(style, times(5)).addLayerBelow(any(Layer.class), Mockito.<String>any()); + } + + @Test public void updateForegroundOffset_foregroundIconPropertyIsUpdated() { LayerSourceProvider sourceProvider = buildLayerProvider(); GeoJsonSource locationSource = mock(GeoJsonSource.class); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationModesActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationModesActivity.java index 618032f5e0..808ed61927 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationModesActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationModesActivity.java @@ -12,6 +12,7 @@ import android.view.MenuItem; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.Toast; + import com.mapbox.android.core.location.LocationEngineRequest; import com.mapbox.android.core.permissions.PermissionsListener; import com.mapbox.android.core.permissions.PermissionsManager; @@ -43,7 +44,7 @@ public class LocationModesActivity extends AppCompatActivity implements OnMapRea private LocationComponent locationComponent; private MapboxMap mapboxMap; - private boolean customStyle; + private boolean defaultStyle = false; private static final String SAVED_STATE_CAMERA = "saved_state_camera"; private static final String SAVED_STATE_RENDER = "saved_state_render"; @@ -124,18 +125,6 @@ public class LocationModesActivity extends AppCompatActivity implements OnMapRea this.mapboxMap = mapboxMap; mapboxMap.setStyle(Style.MAPBOX_STREETS, style -> { - int[] padding; - if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { - padding = new int[] {0, 750, 0, 0}; - } else { - padding = new int[] {0, 250, 0, 0}; - } - - LocationComponentOptions options = LocationComponentOptions.builder(this) - .padding(padding) - .layerBelow("waterway-label") - .build(); - locationComponent = mapboxMap.getLocationComponent(); locationComponent.activateLocationComponent(this, style, true, new LocationEngineRequest.Builder(750) @@ -143,7 +132,7 @@ public class LocationModesActivity extends AppCompatActivity implements OnMapRea .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY) .build() ); - locationComponent.applyStyle(options); + toggleStyle(); locationComponent.setLocationComponentEnabled(true); locationComponent.addOnLocationClickListener(this); locationComponent.addOnCameraTrackingChangedListener(this); @@ -195,10 +184,25 @@ public class LocationModesActivity extends AppCompatActivity implements OnMapRea return; } - customStyle = !customStyle; - locationComponent.applyStyle( - this, - customStyle ? R.style.CustomLocationComponent : R.style.mapbox_LocationComponent); + defaultStyle = !defaultStyle; + LocationComponentOptions options = LocationComponentOptions.createFromAttributes( + this, defaultStyle ? R.style.mapbox_LocationComponent : R.style.CustomLocationComponent); + + if (defaultStyle) { + int[] padding; + if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { + padding = new int[] {0, 750, 0, 0}; + } else { + padding = new int[] {0, 250, 0, 0}; + } + + options = options.toBuilder() + .padding(padding) + .layerBelow("road-label") + .build(); + } + + locationComponent.applyStyle(options); } private void toggleMapStyle() { |