From 227ddffee60376efd2f73fcdb0b9f578a85f3631 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Tue, 9 Feb 2016 12:39:04 +0100 Subject: [PATCH] [android] #3745 - MapboxMap.OnCameraChangeListener :camera: --- .../com/mapbox/mapboxsdk/maps/MapboxMap.java | 107 +++++++++++++++--- .../mapboxsdk/testapp/CameraActivity.java | 7 ++ .../mapboxsdk/testapp/MainActivity.java | 8 ++ 3 files changed, 108 insertions(+), 14 deletions(-) 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 a86b2b97c..067923b05 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 @@ -5,6 +5,7 @@ import android.content.Context; import android.location.Location; import android.os.Bundle; +import android.os.SystemClock; import android.support.annotation.FloatRange; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -60,6 +61,7 @@ public class MapboxMap { private MapboxMap.OnMyLocationTrackingModeChangeListener mOnMyLocationTrackingModeChangeListener; private MapboxMap.OnMyBearingTrackingModeChangeListener mOnMyBearingTrackingModeChangeListener; private MapboxMap.OnFpsChangedListener mOnFpsChangedListener; + private MapboxMap.OnCameraChangeListener mOnCameraChangeListener; MapboxMap(@NonNull MapView mapView) { mMapView = mapView; @@ -106,14 +108,7 @@ public class MapboxMap { */ public final CameraPosition getCameraPosition() { if (mInvalidCameraPosition) { - // Camera position has changed, need to regenerate position - mCameraPosition = new CameraPosition.Builder(true) - .bearing((float) mMapView.getBearing()) - .target(mMapView.getLatLng()) - .tilt((float) mMapView.getTilt()) - .zoom((float) mMapView.getZoom()) - .build(); - mInvalidCameraPosition = false; + invalidateCameraPosition(); } return mCameraPosition; } @@ -140,6 +135,9 @@ public class MapboxMap { public final void moveCamera(CameraUpdate update) { mCameraPosition = update.getCameraPosition(this); mMapView.jumpTo(mCameraPosition.bearing, mCameraPosition.target, mCameraPosition.tilt, mCameraPosition.zoom); + if (mOnCameraChangeListener != null) { + mOnCameraChangeListener.onCameraChange(mCameraPosition); + } } /** @@ -176,7 +174,25 @@ public class MapboxMap { @UiThread public final void easeCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) { mCameraPosition = update.getCameraPosition(this); - mMapView.easeTo(mCameraPosition.bearing, mCameraPosition.target, getDurationNano(durationMs), mCameraPosition.tilt, mCameraPosition.zoom, callback); + mMapView.easeTo(mCameraPosition.bearing, mCameraPosition.target, getDurationNano(durationMs), mCameraPosition.tilt, mCameraPosition.zoom, new CancelableCallback() { + @Override + public void onCancel() { + if (callback != null) { + callback.onCancel(); + } + } + + @Override + public void onFinish() { + if (mOnCameraChangeListener != null) { + mOnCameraChangeListener.onCameraChange(mCameraPosition); + } + + if (callback != null) { + callback.onFinish(); + } + } + }); } /** @@ -228,7 +244,25 @@ public class MapboxMap { @UiThread public final void animateCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) { mCameraPosition = update.getCameraPosition(this); - mMapView.flyTo(mCameraPosition.bearing, mCameraPosition.target, getDurationNano(durationMs), mCameraPosition.tilt, mCameraPosition.zoom, callback); + mMapView.flyTo(mCameraPosition.bearing, mCameraPosition.target, getDurationNano(durationMs), mCameraPosition.tilt, mCameraPosition.zoom, new CancelableCallback() { + @Override + public void onCancel() { + if (callback != null) { + callback.onCancel(); + } + } + + @Override + public void onFinish() { + if (mOnCameraChangeListener != null) { + mOnCameraChangeListener.onCameraChange(mCameraPosition); + } + + if (callback != null) { + callback.onFinish(); + } + } + }); } // internal time layer conversion @@ -236,6 +270,19 @@ public class MapboxMap { return durationMs > 0 ? TimeUnit.NANOSECONDS.convert(durationMs, TimeUnit.MILLISECONDS) : 0; } + private void invalidateCameraPosition() { + mInvalidCameraPosition = false; + mCameraPosition = new CameraPosition.Builder(true) + .bearing((float) mMapView.getBearing()) + .target(mMapView.getLatLng()) + .tilt((float) mMapView.getTilt()) + .zoom((float) mMapView.getZoom()) + .build(); + if (mOnCameraChangeListener != null) { + mOnCameraChangeListener.onCameraChange(mCameraPosition); + } + } + // // ZOOM // @@ -739,6 +786,17 @@ public class MapboxMap { // Map events // + /** + * Sets a callback that's invoked on every change in camera position. + * + * @param listener The callback that's invoked on every camera change position. + * To unset the callback, use null. + */ + @UiThread + public void setOnCameraChangeListener(@Nullable OnCameraChangeListener listener) { + mOnCameraChangeListener = listener; + } + /** * Sets a callback that's invoked on every frame rendered to the map view. * @@ -1081,6 +1139,20 @@ public class MapboxMap { void onScroll(); } + /** + * Interface definition for a callback to be invoked for when the camera changes position. + */ + public interface OnCameraChangeListener { + /** + * Called after the camera position has changed. During an animation, + * this listener may not be notified of intermediate camera positions. + * It is always called for the final position in the animation. + * + * @param position The CameraPosition at the end of the last camera change. + */ + void onCameraChange(CameraPosition position); + } + /** * Interface definition for a callback to be invoked on every frame rendered to the map view. * @@ -1247,13 +1319,20 @@ public class MapboxMap { } private class MapChangeCameraPositionListener implements MapView.OnMapChangedListener { + + private static final long UPDATE_RATE_MS = 400; + private long mPreviousUpdateTimestamp = 0; + @Override public void onMapChanged(@MapView.MapChange int change) { - if (!mInvalidCameraPosition && (change == MapView.REGION_DID_CHANGE - || change == MapView.REGION_DID_CHANGE_ANIMATED - || change == MapView.REGION_WILL_CHANGE - || change == MapView.REGION_WILL_CHANGE_ANIMATED)) { + if (change >= MapView.REGION_WILL_CHANGE && change <= MapView.REGION_DID_CHANGE_ANIMATED) { mInvalidCameraPosition = true; + long currentTime = SystemClock.elapsedRealtime(); + if (currentTime < mPreviousUpdateTimestamp) { + return; + } + invalidateCameraPosition(); + mPreviousUpdateTimestamp = currentTime + UPDATE_RATE_MS; } } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java index 9ccbc34c3..bc63927ac 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java @@ -10,6 +10,7 @@ import android.view.MenuItem; import android.view.View; import android.widget.Toast; +import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.maps.CameraUpdateFactory; @@ -47,6 +48,12 @@ public class CameraActivity extends AppCompatActivity { public void onMapReady(@NonNull final MapboxMap mapboxMap) { // set a style mapboxMap.setStyle(Style.MAPBOX_STREETS); + mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() { + @Override + public void onCameraChange(CameraPosition position) { + Log.v(MapboxConstants.TAG, position.toString()); + } + }); // handle move button clicks findViewById(R.id.cameraMoveButton).setOnClickListener(new View.OnClickListener() { diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java index 3a473f63c..ff7343182 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java @@ -220,6 +220,14 @@ public class MainActivity extends AppCompatActivity { } }); + + mMapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() { + @Override + public void onCameraChange(CameraPosition position) { + Log.v(TAG, "OnCameraChange : " + position); + } + }); + changeMapStyle(mSelectedStyle); } });