From 5f7c224e76be7dc75744869dc892fcb92be28e24 Mon Sep 17 00:00:00 2001 From: Kevin Li Date: Wed, 27 May 2020 17:56:43 +0800 Subject: [PATCH] Update location while camera move in tracking mode (#378) * Update location while camera move in tracking mode * Move update focal point logic into OnCameraMoveListener * Fix review comments. * Update testcases --- .../location/LocationCameraController.java | 25 +++++++++++-------- .../com/mapbox/mapboxsdk/maps/Transform.java | 2 +- .../LocationCameraControllerTest.java | 20 ++++++++++++--- .../mapbox/mapboxsdk/maps/TransformTest.kt | 7 +++++- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java index e00cc3884..c4c27a5e8 100644 --- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java +++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java @@ -35,7 +35,6 @@ final class LocationCameraController { private final Transform transform; private final OnCameraTrackingChangedListener internalCameraTrackingChangedListener; private LocationComponentOptions options; - private boolean adjustFocalPoint; private final MoveGestureDetector moveGestureDetector; private final OnCameraMoveInvalidateListener onCameraMoveInvalidateListener; @@ -44,6 +43,7 @@ final class LocationCameraController { private final AndroidGesturesManager internalGesturesManager; private boolean isTransitioning; + private LatLng lastLocation; LocationCameraController( Context context, @@ -61,7 +61,7 @@ final class LocationCameraController { mapboxMap.addOnRotateListener(onRotateListener); mapboxMap.addOnFlingListener(onFlingListener); mapboxMap.addOnMoveListener(onMoveListener); - + mapboxMap.addOnCameraMoveListener(onCameraMoveListener); this.internalCameraTrackingChangedListener = internalCameraTrackingChangedListener; this.onCameraMoveInvalidateListener = onCameraMoveInvalidateListener; initializeOptions(options); @@ -76,6 +76,7 @@ final class LocationCameraController { AndroidGesturesManager initialGesturesManager, AndroidGesturesManager internalGesturesManager) { this.mapboxMap = mapboxMap; + mapboxMap.addOnCameraMoveListener(onCameraMoveListener); this.transform = transform; this.moveGestureDetector = moveGestureDetector; this.internalCameraTrackingChangedListener = internalCameraTrackingChangedListener; @@ -207,15 +208,9 @@ final class LocationCameraController { if (isTransitioning) { return; } - + lastLocation = latLng; transform.moveCamera(mapboxMap, CameraUpdateFactory.newLatLng(latLng), null); onCameraMoveInvalidateListener.onInvalidateCameraMove(); - - if (adjustFocalPoint) { - PointF focalPoint = mapboxMap.getProjection().toScreenLocation(latLng); - mapboxMap.getUiSettings().setFocalPoint(focalPoint); - adjustFocalPoint = false; - } } private void setZoom(float zoom) { @@ -312,7 +307,6 @@ final class LocationCameraController { private void adjustGesturesThresholds() { if (options.trackingGesturesManagement()) { if (isLocationTracking()) { - adjustFocalPoint = true; moveGestureDetector.setMoveThreshold(options.trackingInitialMoveThreshold()); } else { moveGestureDetector.setMoveThreshold(0f); @@ -355,6 +349,17 @@ final class LocationCameraController { } } + private MapboxMap.OnCameraMoveListener onCameraMoveListener = new MapboxMap.OnCameraMoveListener() { + + @Override + public void onCameraMove() { + if (isLocationTracking() && lastLocation != null && options.trackingGesturesManagement()) { + PointF focalPoint = mapboxMap.getProjection().toScreenLocation(lastLocation); + mapboxMap.getUiSettings().setFocalPoint(focalPoint); + } + } + }; + @NonNull @VisibleForTesting MapboxMap.OnMoveListener onMoveListener = new MapboxMap.OnMoveListener() { diff --git a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index efd3efe8c..126daa336 100644 --- a/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -112,8 +112,8 @@ public final class Transform implements MapView.OnCameraDidChangeListener { cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION); nativeMap.jumpTo(cameraPosition.target, cameraPosition.zoom, cameraPosition.tilt, cameraPosition.bearing, cameraPosition.padding); - cameraChangeDispatcher.onCameraIdle(); invalidateCameraPosition(); + cameraChangeDispatcher.onCameraIdle(); handler.post(new Runnable() { @Override public void run() { diff --git a/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java b/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java index acf5a9dac..fb67df099 100644 --- a/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java +++ b/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java @@ -283,13 +283,22 @@ public class LocationCameraControllerTest { @Test public void onNewLatLngValue_focalPointIsAdjusted() { MapboxMap mapboxMap = mock(MapboxMap.class); - UiSettings uiSettings = mock(UiSettings.class); - when(mapboxMap.getUiSettings()).thenReturn(uiSettings); + Transform transform = mock(Transform.class); + + final MapboxMap.OnCameraMoveListener[] listener = {null}; + doAnswer(new Answer() { + @Override + public Void answer(InvocationOnMock invocation) { + listener[0] = (MapboxMap.OnCameraMoveListener) invocation.getArguments()[0]; + return null; + } + }).when(mapboxMap).addOnCameraMoveListener(any(MapboxMap.OnCameraMoveListener.class)); + Projection projection = mock(Projection.class); PointF pointF = mock(PointF.class); when(projection.toScreenLocation(any(LatLng.class))).thenReturn(pointF); when(mapboxMap.getProjection()).thenReturn(projection); - LocationCameraController camera = buildCamera(mapboxMap); + LocationCameraController camera = buildCamera(mapboxMap, transform); LocationComponentOptions options = mock(LocationComponentOptions.class); when(options.trackingGesturesManagement()).thenReturn(true); camera.initializeOptions(options); @@ -297,7 +306,12 @@ public class LocationCameraControllerTest { LatLng latLng = mock(LatLng.class); getAnimationListener(ANIMATOR_CAMERA_LATLNG, camera.getAnimationListeners()).onNewAnimationValue(latLng); + verify(transform).moveCamera(any(MapboxMap.class), any(CameraUpdate.class), + nullable(MapboxMap.CancelableCallback.class)); + UiSettings uiSettings = mock(UiSettings.class); + when(mapboxMap.getUiSettings()).thenReturn(uiSettings); + listener[0].onCameraMove(); verify(uiSettings).setFocalPoint(pointF); } diff --git a/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/TransformTest.kt b/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/TransformTest.kt index d157687e0..b62fbd6b6 100644 --- a/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/TransformTest.kt +++ b/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/TransformTest.kt @@ -15,10 +15,11 @@ class TransformTest { private lateinit var mapView: MapView private lateinit var nativeMapView: NativeMap private lateinit var transform: Transform + private lateinit var cameraChangeDispatcher: CameraChangeDispatcher @Before fun setup() { - val cameraChangeDispatcher = spyk() + cameraChangeDispatcher = spyk() mapView = mockk() nativeMapView = mockk() transform = Transform(mapView, nativeMapView, cameraChangeDispatcher) @@ -45,8 +46,12 @@ class TransformTest { val target = LatLng(1.0, 2.0) val expected = CameraPosition.Builder().target(target).build() val update = CameraUpdateFactory.newCameraPosition(expected) + + transform.cameraPosition + every { nativeMapView.cameraPosition } returns expected transform.moveCamera(mapboxMap, update, callback) + verify { cameraChangeDispatcher.onCameraMove() } verify { nativeMapView.jumpTo(target, -1.0, -1.0, -1.0, null) } verify { callback.onFinish() } }