diff options
author | clydebarrow <github@cps.sr20.org> | 2016-10-04 18:13:02 +1100 |
---|---|---|
committer | Tobrun <tobrun.van.nuland@gmail.com> | 2016-10-05 17:10:45 +0200 |
commit | a4b0e2f30c38986aedc2dc728adbd383912f4bee (patch) | |
tree | d8b2be2482e4bdfa0b3751232765b08d4b878077 /platform | |
parent | 214ec4e96ad71d8ffefe1c12292ec77b58bd3fb2 (diff) | |
download | qtlocation-mapboxgl-a4b0e2f30c38986aedc2dc728adbd383912f4bee.tar.gz |
[android] Revise handling of tracking modes and interactions
with touch gestures.
This fixes issues #6549 and #6567. Also pertinent to #6557.
Additional code has been added to the test app (Activity "User Tracking
Mode") to test.
A potential race condition in the MapboxMap#easeCamera() methods where
a camera change generated by tracking which could have reset the tracking
modes has been eliminated by factoring out a new method
MapboxMap#easeCameraInternal().
Diffstat (limited to 'platform')
9 files changed, 239 insertions, 164 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 b4737809fe..10ebecee27 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 @@ -107,6 +107,8 @@ public class MapboxConstants { public static final String STATE_MY_LOCATION_ENABLED = "myLocationEnabled"; public static final String STATE_MY_LOCATION_TRACKING_MODE = "myLocationTracking"; public static final String STATE_MY_BEARING_TRACKING_MODE = "myBearingTracking"; + public static final String STATE_MY_LOCATION_TRACKING_DISMISS = "myLocationTrackingDismiss"; + public static final String STATE_MY_BEARING_TRACKING_DISMISS = "myBearingTrackingDismiss"; public static final String STATE_COMPASS_ENABLED = "compassEnabled"; public static final String STATE_COMPASS_GRAVITY = "compassGravity"; public static final String STATE_COMPASS_MARGIN_LEFT = "compassMarginLeft"; 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 e215c5d0da..b8a37c7439 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 @@ -444,7 +444,11 @@ public class MapView extends FrameLayout { savedInstanceState.getInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE)); //noinspection ResourceType trackingSettings.setMyBearingTrackingMode( - savedInstanceState.getInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE)); + savedInstanceState.getInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE)); + trackingSettings.setDismissLocationTrackingOnGesture( + savedInstanceState.getBoolean(MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, true)); + trackingSettings.setDismissBearingTrackingOnGesture( + savedInstanceState.getBoolean(MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, true)); } else if (savedInstanceState == null) { // Start Telemetry (authorization determined in initial MapboxEventManager constructor) Log.i(MapView.class.getCanonicalName(), "MapView start Telemetry..."); @@ -517,6 +521,8 @@ public class MapView extends FrameLayout { TrackingSettings trackingSettings = mapboxMap.getTrackingSettings(); outState.putInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, trackingSettings.getMyLocationTrackingMode()); outState.putInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, trackingSettings.getMyBearingTrackingMode()); + outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, trackingSettings.isDismissLocationTrackingOnGesture()); + outState.putBoolean(MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, trackingSettings.isDismissBearingTrackingOnGesture()); // UiSettings UiSettings uiSettings = mapboxMap.getUiSettings(); @@ -1822,7 +1828,7 @@ public class MapView extends FrameLayout { (tapPoint.y - averageIconHeight / 2 - toleranceTopBottom) / screenDensity, (tapPoint.x + averageIconWidth / 2 + toleranceSides) / screenDensity, (tapPoint.y + averageIconHeight / 2 + toleranceTopBottom) / screenDensity); - + List<Marker> nearbyMarkers = getMarkersInRect(tapRect); long newSelectedMarkerId = -1; @@ -1890,12 +1896,11 @@ public class MapView extends FrameLayout { // Called for flings @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - if (destroyed || !mapboxMap.getUiSettings().isScrollGesturesEnabled()) { + if (destroyed || !mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) { return false; } - // reset tracking modes if gesture occurs - resetTrackingModesIfRequired(); + resetTrackingModesIfRequired(true, false); // Fling the map float ease = 0.25f; @@ -1927,7 +1932,7 @@ public class MapView extends FrameLayout { if (!scrollInProgress) { scrollInProgress = true; } - if (destroyed || !mapboxMap.getUiSettings().isScrollGesturesEnabled()) { + if (destroyed || !mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) { return false; } @@ -1937,9 +1942,8 @@ public class MapView extends FrameLayout { requestDisallowInterceptTouchEvent(true); - // reset tracking modes if gesture occurs - resetTrackingModesIfRequired(); - + // reset tracking if needed + resetTrackingModesIfRequired(true, false); // Cancel any animation nativeMapView.cancelTransitions(); @@ -1967,9 +1971,6 @@ public class MapView extends FrameLayout { return false; } - // reset tracking modes if gesture occurs - resetTrackingModesIfRequired(); - beginTime = detector.getEventTime(); trackGestureEvent(MapboxEvent.GESTURE_PINCH_START, detector.getFocusX(), detector.getFocusY()); return true; @@ -2020,6 +2021,11 @@ public class MapView extends FrameLayout { // Gesture is a quickzoom if there aren't two fingers quickZoom = !twoTap; + // make an assumption here; if the zoom center is specified by the gesture, it's NOT going + // to be in the center of the map. Therefore the zoom will translate the map center, so tracking + // should be disabled. + + resetTrackingModesIfRequired(!quickZoom, false); // Scale the map if (focalPoint != null) { // arround user provided focal point @@ -2046,12 +2052,8 @@ public class MapView extends FrameLayout { // Called when two fingers first touch the screen @Override public boolean onRotateBegin(RotateGestureDetector detector) { - if (destroyed || !mapboxMap.getUiSettings().isRotateGesturesEnabled()) { + if (destroyed || !mapboxMap.getTrackingSettings().isRotateGestureCurrentlyEnabled()) return false; - } - - // reset tracking modes if gesture occurs - resetTrackingModesIfRequired(); beginTime = detector.getEventTime(); trackGestureEvent(MapboxEvent.GESTURE_ROTATION_START, detector.getFocusX(), detector.getFocusY()); @@ -2070,9 +2072,8 @@ public class MapView extends FrameLayout { // Called for rotation @Override public boolean onRotate(RotateGestureDetector detector) { - if (destroyed || !mapboxMap.getUiSettings().isRotateGesturesEnabled()) { + if (destroyed || !mapboxMap.getTrackingSettings().isRotateGestureCurrentlyEnabled()) return false; - } if (dragStarted) { return false; @@ -2100,6 +2101,11 @@ public class MapView extends FrameLayout { // Cancel any animation nativeMapView.cancelTransitions(); + // rotation constitutes translation of anything except the center of + // rotation, so cancel both location and bearing tracking if required + + resetTrackingModesIfRequired(true, true); + // Get rotate value double bearing = nativeMapView.getBearing(); bearing += detector.getRotationDegreesDelta(); @@ -2130,9 +2136,6 @@ public class MapView extends FrameLayout { return false; } - // reset tracking modes if gesture occurs - resetTrackingModesIfRequired(); - beginTime = detector.getEventTime(); trackGestureEvent(MapboxEvent.GESTURE_PITCH_START, detector.getFocusX(), detector.getFocusY()); return true; @@ -2234,7 +2237,7 @@ public class MapView extends FrameLayout { return true; case KeyEvent.KEYCODE_DPAD_LEFT: - if (!mapboxMap.getUiSettings().isScrollGesturesEnabled()) { + if (!mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) { return false; } @@ -2246,7 +2249,7 @@ public class MapView extends FrameLayout { return true; case KeyEvent.KEYCODE_DPAD_RIGHT: - if (!mapboxMap.getUiSettings().isScrollGesturesEnabled()) { + if (!mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) { return false; } @@ -2258,7 +2261,7 @@ public class MapView extends FrameLayout { return true; case KeyEvent.KEYCODE_DPAD_UP: - if (!mapboxMap.getUiSettings().isScrollGesturesEnabled()) { + if (!mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) { return false; } @@ -2270,7 +2273,7 @@ public class MapView extends FrameLayout { return true; case KeyEvent.KEYCODE_DPAD_DOWN: - if (!mapboxMap.getUiSettings().isScrollGesturesEnabled()) { + if (!mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) { return false; } @@ -2350,7 +2353,7 @@ public class MapView extends FrameLayout { switch (event.getActionMasked()) { // The trackball was rotated case MotionEvent.ACTION_MOVE: - if (!mapboxMap.getUiSettings().isScrollGesturesEnabled()) { + if (!mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) { return false; } @@ -2634,14 +2637,26 @@ public class MapView extends FrameLayout { ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; } - void resetTrackingModesIfRequired() { + /** + * Reset the tracking modes as necessary. Location tracking is reset if the map center is changed, + * bearing tracking if there is a rotation. + * + * @param translate + * @param rotate + */ + void resetTrackingModesIfRequired(boolean translate, boolean rotate) { TrackingSettings trackingSettings = mapboxMap.getTrackingSettings(); - if (trackingSettings.isDismissLocationTrackingOnGesture()) { + + // if tracking is on, and we should dismiss tracking with gestures, and this is a scroll action, turn tracking off + if (translate && !trackingSettings.isLocationTrackingDisabled() && trackingSettings.isDismissLocationTrackingOnGesture()) resetLocationTrackingMode(); - } - if (trackingSettings.isDismissBearingTrackingOnGesture()) { + // reset bearing tracking only on rotate + if (rotate && !trackingSettings.isBearingTrackingDisabled() && trackingSettings.isDismissBearingTrackingOnGesture()) resetBearingTrackingMode(); - } + } + + void resetTrackingModesIfRequired(CameraPosition cameraPosition ) { + resetTrackingModesIfRequired(cameraPosition.target != null, cameraPosition.bearing != -1); } private void resetLocationTrackingMode() { 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 a9e74bbb01..458f14d8bc 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 @@ -390,11 +390,9 @@ public class MapboxMap { @UiThread public final void moveCamera(CameraUpdate update, MapboxMap.CancelableCallback callback) { // dismiss tracking, moving camera is equal to a gesture - if (!trackingSettings.isLocationTrackingDisabled()) { - mapView.resetTrackingModesIfRequired(); - } cameraPosition = update.getCameraPosition(this); + mapView.resetTrackingModesIfRequired(cameraPosition); mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom); if (callback != null) { callback.onFinish(); @@ -435,6 +433,8 @@ public class MapboxMap { * unless specified within {@link CameraUpdate}. A callback can be used to be notified when * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it * will return the current location of the camera in flight. + * <p> + * Note that this will cancel location tracking mode if enabled. * * @param update The change that should be applied to the camera. * @param durationMs The duration of the animation in milliseconds. This must be strictly @@ -458,31 +458,38 @@ public class MapboxMap { @UiThread public final void easeCamera( - CameraUpdate update, int durationMs, boolean easingInterpolator, final MapboxMap.CancelableCallback callback) { + CameraUpdate update, int durationMs, boolean easingInterpolator, final MapboxMap.CancelableCallback callback) { // dismiss tracking, moving camera is equal to a gesture - if (!trackingSettings.isLocationTrackingDisabled()) { - mapView.resetTrackingModesIfRequired(); - } + CameraPosition cameraPosition = update.getCameraPosition(this); + mapView.resetTrackingModesIfRequired(cameraPosition); + easeCameraInternal(cameraPosition, durationMs, easingInterpolator, callback); + } - cameraPosition = update.getCameraPosition(this); + /** + * Internal use only. + * Used by tracking actions. + */ + @UiThread + public final void easeCameraInternal( + CameraPosition cameraPosition, int durationMs, boolean easingInterpolator, final MapboxMap.CancelableCallback callback) { mapView.easeTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt, - cameraPosition.zoom, easingInterpolator, new CancelableCallback() { - @Override - public void onCancel() { - if (callback != null) { - callback.onCancel(); - } - invalidateCameraPosition(); - } + cameraPosition.zoom, easingInterpolator, new CancelableCallback() { + @Override + public void onCancel() { + if (callback != null) { + callback.onCancel(); + } + invalidateCameraPosition(); + } - @Override - public void onFinish() { - if (callback != null) { - callback.onFinish(); - } - invalidateCameraPosition(); - } - }); + @Override + public void onFinish() { + if (callback != null) { + callback.onFinish(); + } + invalidateCameraPosition(); + } + }); } /** @@ -553,33 +560,31 @@ public class MapboxMap { @UiThread public final void animateCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) { // dismiss tracking, moving camera is equal to a gesture - if (!trackingSettings.isLocationTrackingDisabled() && trackingSettings.isDismissLocationTrackingOnGesture()) { - mapView.resetTrackingModesIfRequired(); - } - + cameraPosition = update.getCameraPosition(this); + mapView.resetTrackingModesIfRequired(cameraPosition); mapView.flyTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt, - cameraPosition.zoom, new CancelableCallback() { - @Override - public void onCancel() { - if (callback != null) { - callback.onCancel(); - } - invalidateCameraPosition(); - } + cameraPosition.zoom, new CancelableCallback() { + @Override + public void onCancel() { + if (callback != null) { + callback.onCancel(); + } + invalidateCameraPosition(); + } - @Override - public void onFinish() { - if (onCameraChangeListener != null) { - onCameraChangeListener.onCameraChange(cameraPosition); - } + @Override + public void onFinish() { + if (onCameraChangeListener != null) { + onCameraChangeListener.onCameraChange(cameraPosition); + } - if (callback != null) { - callback.onFinish(); - } - invalidateCameraPosition(); - } - }); + if (callback != null) { + callback.onFinish(); + } + invalidateCameraPosition(); + } + }); } /** @@ -1706,7 +1711,7 @@ public class MapboxMap { public void setMyLocationEnabled(boolean enabled) { if (!mapView.isPermissionsAccepted()) { Log.e(MapboxConstants.TAG, "Could not activate user location tracking: " - + "user did not accept the permission or permissions were not requested."); + + "user did not accept the permission or permissions were not requested."); return; } myLocationEnabled = enabled; @@ -1838,7 +1843,6 @@ public class MapboxMap { return mapView.getNativeMapView().queryRenderedFeatures(coordinates, layerIds); } - // // Interfaces // diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java index f2a49f102b..9564578a53 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java @@ -45,7 +45,6 @@ public class TrackingSettings { public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) { this.myLocationTrackingMode = myLocationTrackingMode; mapView.setMyLocationTrackingMode(myLocationTrackingMode); - validateGesturesForLocationTrackingMode(); } /** @@ -80,7 +79,6 @@ public class TrackingSettings { public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) { this.myBearingTrackingMode = myBearingTrackingMode; mapView.setMyBearingTrackingMode(myBearingTrackingMode); - validateGesturesForBearingTrackingMode(); } /** @@ -135,7 +133,6 @@ public class TrackingSettings { public void setDismissAllTrackingOnGesture(boolean dismissTrackingOnGesture) { dismissLocationTrackingOnGesture = dismissTrackingOnGesture; dismissBearingTrackingOnGesture = dismissTrackingOnGesture; - validateAllGesturesForTrackingModes(); } /** @@ -145,7 +142,6 @@ public class TrackingSettings { */ public void setDismissLocationTrackingOnGesture(boolean dismissLocationTrackingOnGesture) { this.dismissLocationTrackingOnGesture = dismissLocationTrackingOnGesture; - validateGesturesForLocationTrackingMode(); } /** @@ -164,7 +160,6 @@ public class TrackingSettings { */ public void setDismissBearingTrackingOnGesture(boolean dismissBearingTrackingOnGesture) { this.dismissBearingTrackingOnGesture = dismissBearingTrackingOnGesture; - validateGesturesForBearingTrackingMode(); } /** @@ -186,42 +181,37 @@ public class TrackingSettings { } /** - * Retyrns uf bearing tracking is disabled + * Is bearing tracking disabled? * - * @return True if bearing tracking will be disabled. + * @return True if bearing tracking is disabled. */ public boolean isBearingTrackingDisabled() { return myBearingTrackingMode == MyBearingTracking.NONE; } - private void validateAllGesturesForTrackingModes() { - validateGesturesForBearingTrackingMode(); - validateGesturesForLocationTrackingMode(); - } - - private void validateGesturesForLocationTrackingMode() { - int myLocationTrackingMode = getMyLocationTrackingMode(); - if (!dismissLocationTrackingOnGesture) { - if (myLocationTrackingMode == MyLocationTracking.TRACKING_NONE) { - uiSettings.setScrollGesturesEnabled(true); - } else { - uiSettings.setScrollGesturesEnabled(false); - } - } else { - uiSettings.setScrollGesturesEnabled(true); - } - } - - private void validateGesturesForBearingTrackingMode() { - int myBearingTrackingMode = getMyBearingTrackingMode(); - if (!dismissBearingTrackingOnGesture) { - if (myBearingTrackingMode == MyBearingTracking.NONE || myLocationTrackingMode == MyLocationTracking.TRACKING_NONE) { - uiSettings.setRotateGesturesEnabled(true); - } else { - uiSettings.setRotateGesturesEnabled(false); - } - } else { - uiSettings.setRotateGesturesEnabled(true); - } + /** + * Is the map currently in a state where rotate gestures are recognised? + * This requires both that the user interface has such gestures enabled, + * and that they are not currently blocked by a bearing tracking mode. + */ + + public boolean isRotateGestureCurrentlyEnabled() { + // rotate gestures are recognised if: + // The user settings are enabled AND; + // EITHER bearing tracking is dismissed on gesture OR there is no bearing tracking + + return uiSettings.isRotateGesturesEnabled() && + (dismissBearingTrackingOnGesture || myBearingTrackingMode == MyBearingTracking.NONE); + } + + /** + * Is the map currently in a state where scroll gestures are recognised? + * This requires both that the user interface has such gestures enabled, + * and that they are not currently blocked by a location tracking mode. + */ + + public boolean isScrollGestureCurrentlyEnabled() { + return uiSettings.isScrollGesturesEnabled() && + (dismissLocationTrackingOnGesture || myLocationTrackingMode == MyLocationTracking.TRACKING_NONE); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index 24ab3e7346..6ff6341fdb 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -457,16 +457,16 @@ public class MyLocationView extends View { } public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) { - this.myLocationTrackingMode = myLocationTrackingMode; MyLocationBehaviorFactory factory = new MyLocationBehaviorFactory(); myLocationBehavior = factory.getBehavioralModel(myLocationTrackingMode); - if (myLocationTrackingMode != MyLocationTracking.TRACKING_NONE && location != null) { + if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW && location != null) { // center map directly if we have a location fix myLocationBehavior.updateLatLng(location); - mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(location))); + mapboxMap.easeCameraInternal(CameraUpdateFactory.newLatLng(new LatLng(location)).getCameraPosition(mapboxMap), 0, false, null); } + this.myLocationTrackingMode = myLocationTrackingMode; invalidate(); update(); } @@ -586,7 +586,7 @@ public class MyLocationView extends View { private void rotateCamera() { CameraPosition.Builder builder = new CameraPosition.Builder(); builder.bearing(currentDegree); - mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), COMPASS_UPDATE_RATE_MS, false /*linear interpolator*/); + mapboxMap.easeCameraInternal(CameraUpdateFactory.newCameraPosition(builder.build()).getCameraPosition(mapboxMap), COMPASS_UPDATE_RATE_MS, false /*linear interpolator*/, null); } @Override @@ -702,7 +702,7 @@ public class MyLocationView extends View { updateAccuracy(location); // ease to new camera position with a linear interpolator - mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), (int) locationUpdateDuration, false /*linear interpolator*/); + mapboxMap.easeCameraInternal(CameraUpdateFactory.newCameraPosition(builder.build()).getCameraPosition(mapboxMap), (int) locationUpdateDuration, false /*linear interpolator*/, null); } @Override @@ -765,7 +765,8 @@ public class MyLocationView extends View { @Override void invalidate() { - screenLocation = projection.toScreenLocation(latLng); + if(latLng != null) + screenLocation = projection.toScreenLocation(latLng); MyLocationView.this.invalidate(); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java index 72abd95ba8..301636611c 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java @@ -50,7 +50,6 @@ public class MyLocationDrawableActivity extends AppCompatActivity implements Loc findViewById(R.id.progress).setVisibility(View.GONE); MapboxMapOptions mapboxMapOptions = new MapboxMapOptions(); - mapboxMapOptions.accessToken(getString(R.string.mapbox_access_token)); mapboxMapOptions.styleUrl(Style.MAPBOX_STREETS); // configure MyLocationView drawables diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java index d89f3e2cf8..43b4126a72 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java @@ -30,17 +30,27 @@ import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; import com.mapbox.mapboxsdk.maps.TrackingSettings; +import com.mapbox.mapboxsdk.maps.UiSettings; import com.mapbox.mapboxsdk.testapp.R; public class MyLocationTrackingModeActivity extends AppCompatActivity - implements MapboxMap.OnMyLocationChangeListener, AdapterView.OnItemSelectedListener { + implements MapboxMap.OnMyLocationChangeListener, AdapterView.OnItemSelectedListener { + public static final int TRACKING_NONE_INDEX = 0; + public static final int TRACKING_FOLLOW_INDEX = 1; + public static final int BEARING_NONE_INDEX = 0; + public static final int BEARING_GPS_INDEX = 1; + public static final int BEARING_COMPASS_INDEX = 2; private MapView mapView; private MapboxMap mapboxMap; private Spinner locationSpinner; private Spinner bearingSpinner; private Location location; private static final int PERMISSIONS_LOCATION = 0; + private MenuItem dismissLocationTrackingOnGestureItem; + private MenuItem dismissBearingTrackingOnGestureItem; + private MenuItem enableRotateGesturesItem; + private MenuItem enableScrollGesturesItem; @Override protected void onCreate(final Bundle savedInstanceState) { @@ -57,53 +67,66 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity actionBar.setDisplayShowHomeEnabled(true); } + locationSpinner = (Spinner) findViewById(R.id.spinner_location); + ArrayAdapter<CharSequence> locationTrackingAdapter = ArrayAdapter.createFromResource( + actionBar.getThemedContext(), R.array.user_tracking_mode, android.R.layout.simple_spinner_item); + locationTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + locationSpinner.setAdapter(locationTrackingAdapter); + + bearingSpinner = (Spinner) findViewById(R.id.spinner_bearing); + ArrayAdapter<CharSequence> bearingTrackingAdapter = ArrayAdapter.createFromResource( + actionBar.getThemedContext(), R.array.user_bearing_mode, android.R.layout.simple_spinner_item); + bearingTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + bearingSpinner.setAdapter(bearingTrackingAdapter); + mapView = (MapView) findViewById(R.id.mapView); mapView.onCreate(savedInstanceState); + mapView.getMapAsync(new OnMapReadyCallback() { @Override public void onMapReady(@NonNull MapboxMap mapboxMap) { MyLocationTrackingModeActivity.this.mapboxMap = mapboxMap; - // disable dismissal when a gesture occurs - TrackingSettings trackingSettings = mapboxMap.getTrackingSettings(); - trackingSettings.setDismissLocationTrackingOnGesture(false); - trackingSettings.setDismissBearingTrackingOnGesture(false); - - mapboxMap.setOnMyLocationChangeListener(MyLocationTrackingModeActivity.this); - - ArrayAdapter<CharSequence> locationTrackingAdapter = ArrayAdapter.createFromResource( - actionBar.getThemedContext(), R.array.user_tracking_mode, android.R.layout.simple_spinner_item); - locationTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - locationSpinner = (Spinner) findViewById(R.id.spinner_location); - locationSpinner.setAdapter(locationTrackingAdapter); locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); - - ArrayAdapter<CharSequence> bearingTrackingAdapter = ArrayAdapter.createFromResource( - actionBar.getThemedContext(), R.array.user_bearing_mode, android.R.layout.simple_spinner_item); - bearingTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - bearingSpinner = (Spinner) findViewById(R.id.spinner_bearing); - bearingSpinner.setAdapter(bearingTrackingAdapter); bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); + setCheckBoxes(); + + mapboxMap.setOnMyLocationChangeListener(MyLocationTrackingModeActivity.this); mapboxMap.setOnMyLocationTrackingModeChangeListener(new MapboxMap.OnMyLocationTrackingModeChangeListener() { @Override public void onMyLocationTrackingModeChange(@MyLocationTracking.Mode int myLocationTrackingMode) { - if (MyLocationTracking.TRACKING_NONE == myLocationTrackingMode) { - locationSpinner.setOnItemSelectedListener(null); - locationSpinner.setSelection(0); - locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); + locationSpinner.setOnItemSelectedListener(null); + switch (myLocationTrackingMode) { + case MyLocationTracking.TRACKING_NONE: + locationSpinner.setSelection(TRACKING_NONE_INDEX); + break; + case MyLocationTracking.TRACKING_FOLLOW: + locationSpinner.setSelection(TRACKING_FOLLOW_INDEX); + break; } + locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); } }); mapboxMap.setOnMyBearingTrackingModeChangeListener(new MapboxMap.OnMyBearingTrackingModeChangeListener() { @Override public void onMyBearingTrackingModeChange(@MyBearingTracking.Mode int myBearingTrackingMode) { - if (MyBearingTracking.NONE == myBearingTrackingMode) { - bearingSpinner.setOnItemSelectedListener(null); - bearingSpinner.setSelection(0); - bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); + bearingSpinner.setOnItemSelectedListener(null); + switch (myBearingTrackingMode) { + case MyBearingTracking.NONE: + bearingSpinner.setSelection(BEARING_NONE_INDEX); + break; + + case MyBearingTracking.GPS: + bearingSpinner.setSelection(BEARING_GPS_INDEX); + break; + + case MyBearingTracking.COMPASS: + bearingSpinner.setSelection(BEARING_COMPASS_INDEX); + break; } + bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this); } }); @@ -118,12 +141,12 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity public void toggleGps(boolean enableGps) { if (enableGps) { if ((ContextCompat.checkSelfPermission(this, - Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) - || (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) - != PackageManager.PERMISSION_GRANTED)) { + Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) + || (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) + != PackageManager.PERMISSION_GRANTED)) { ActivityCompat.requestPermissions(this, new String[]{ - Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION); + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION); } else { enableLocation(true); } @@ -198,25 +221,25 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity TrackingSettings trackingSettings = mapboxMap.getTrackingSettings(); if (parent.getId() == R.id.spinner_location) { switch (position) { - case 0: + case TRACKING_NONE_INDEX: trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE); break; - case 1: + case TRACKING_FOLLOW_INDEX: trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW); break; } } else if (parent.getId() == R.id.spinner_bearing) { switch (position) { - case 0: + case BEARING_NONE_INDEX: trackingSettings.setMyBearingTrackingMode(MyBearingTracking.NONE); break; - case 1: + case BEARING_GPS_INDEX: trackingSettings.setMyBearingTrackingMode(MyBearingTracking.GPS); break; - case 2: + case BEARING_COMPASS_INDEX: trackingSettings.setMyBearingTrackingMode(MyBearingTracking.COMPASS); break; } @@ -261,9 +284,25 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_tracking, menu); + dismissLocationTrackingOnGestureItem = menu.findItem(R.id.action_toggle_dismissible_location); + dismissBearingTrackingOnGestureItem = menu.findItem(R.id.action_toggle_dismissible_bearing); + enableRotateGesturesItem = menu.findItem(R.id.action_toggle_rotate_gesture_enabled); + enableScrollGesturesItem = menu.findItem(R.id.action_toggle_scroll_gesture_enabled); + setCheckBoxes(); return true; } + private void setCheckBoxes() { + if(mapboxMap != null && dismissBearingTrackingOnGestureItem != null) { + TrackingSettings trackingSettings = mapboxMap.getTrackingSettings(); + UiSettings uiSettings = mapboxMap.getUiSettings(); + dismissBearingTrackingOnGestureItem.setChecked(trackingSettings.isDismissBearingTrackingOnGesture()); + dismissLocationTrackingOnGestureItem.setChecked(trackingSettings.isDismissLocationTrackingOnGesture()); + enableRotateGesturesItem.setChecked(uiSettings.isRotateGesturesEnabled()); + enableScrollGesturesItem.setChecked(uiSettings.isScrollGesturesEnabled()); + } + } + @Override public boolean onOptionsItemSelected(MenuItem item) { boolean state; @@ -271,7 +310,7 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity case android.R.id.home: onBackPressed(); return true; - case R.id.action_toggle_dismissible_tracking: + case R.id.action_toggle_dismissible_location: state = !item.isChecked(); mapboxMap.getTrackingSettings().setDismissLocationTrackingOnGesture(state); Toast.makeText(this, "Dismiss tracking mode on gesture = " + state, Toast.LENGTH_SHORT).show(); @@ -283,9 +322,20 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity Toast.makeText(this, "Dismiss bearing mode on gesture = " + state, Toast.LENGTH_SHORT).show(); item.setChecked(state); return true; + case R.id.action_toggle_rotate_gesture_enabled: + state = !item.isChecked(); + mapboxMap.getUiSettings().setRotateGesturesEnabled(state); + Toast.makeText(this, "Rotate gesture enabled = " + state, Toast.LENGTH_SHORT).show(); + item.setChecked(state); + return true; + case R.id.action_toggle_scroll_gesture_enabled: + state = !item.isChecked(); + mapboxMap.getUiSettings().setScrollGesturesEnabled(state); + Toast.makeText(this, "Scroll gesture enabled = " + state, Toast.LENGTH_SHORT).show(); + item.setChecked(state); + return true; default: return super.onOptionsItemSelected(item); } } - } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_tracking.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_tracking.xml index dc2add474c..91424d3f5b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_tracking.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_tracking.xml @@ -4,7 +4,7 @@ <group android:checkableBehavior="all"> <item - android:id="@+id/action_toggle_dismissible_tracking" + android:id="@+id/action_toggle_dismissible_location" android:checkable="true" android:checked="false" android:title="@string/menuitem_title_tracking_mode_dismiss_on_gesture" @@ -15,6 +15,18 @@ android:checked="false" android:title="@string/menuitem_title_bearing_mode_dismiss_on_gesture" app:showAsAction="never" /> + <item + android:id="@+id/action_toggle_rotate_gesture_enabled" + android:checkable="true" + android:checked="false" + android:title="@string/menuitem_title_rotate_gesture_enabled" + app:showAsAction="never" /> + <item + android:id="@+id/action_toggle_scroll_gesture_enabled" + android:checkable="true" + android:checked="false" + android:title="@string/menuitem_title_scroll_gesture_enabled" + app:showAsAction="never" /> </group> </menu>
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml index 128ac715ad..83160feb5b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml @@ -221,5 +221,7 @@ <string name="action_example">Example action</string> <string name="action_settings">Settings</string> + <string name="menuitem_title_rotate_gesture_enabled">Enable rotate gestures</string> + <string name="menuitem_title_scroll_gesture_enabled">Enable scroll gestures</string> </resources> |