Skip to content
This repository was archived by the owner on Aug 8, 2023. It is now read-only.

Commit 2fcbd78

Browse files
[android] hook camera events into compass (#10019)
1 parent 53d072c commit 2fcbd78

File tree

3 files changed

+90
-53
lines changed

3 files changed

+90
-53
lines changed

platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java

+56-6
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747

4848
import timber.log.Timber;
4949

50+
import static com.mapbox.mapboxsdk.maps.widgets.CompassView.TIME_MAP_NORTH_ANIMATION;
51+
import static com.mapbox.mapboxsdk.maps.widgets.CompassView.TIME_WAIT_IDLE;
52+
5053
/**
5154
* <p>
5255
* A {@code MapView} provides an embeddable map interface.
@@ -73,6 +76,7 @@ public class MapView extends FrameLayout {
7376

7477
private MyLocationView myLocationView;
7578
private CompassView compassView;
79+
private PointF focalPoint;
7680
private ImageView attrView;
7781
private ImageView logoView;
7882

@@ -143,7 +147,7 @@ private void initialiseMap() {
143147
addOnMapChangedListener(mapCallback);
144148

145149
// callback for focal point invalidation
146-
FocalPointInvalidator focalPoint = new FocalPointInvalidator(compassView);
150+
final FocalPointInvalidator focalPointInvalidator = new FocalPointInvalidator(createFocalPointChangeListener());
147151

148152
// callback for registering touch listeners
149153
RegisterTouchListener registerTouchListener = new RegisterTouchListener();
@@ -152,13 +156,15 @@ private void initialiseMap() {
152156
CameraZoomInvalidator zoomInvalidator = new CameraZoomInvalidator();
153157

154158
// callback for camera change events
155-
CameraChangeDispatcher cameraChangeDispatcher = new CameraChangeDispatcher();
159+
final CameraChangeDispatcher cameraChangeDispatcher = new CameraChangeDispatcher();
156160

157161
// setup components for MapboxMap creation
158162
Projection proj = new Projection(nativeMapView);
159-
UiSettings uiSettings = new UiSettings(proj, focalPoint, compassView, attrView, logoView);
160-
TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPoint, zoomInvalidator);
161-
MyLocationViewSettings myLocationViewSettings = new MyLocationViewSettings(myLocationView, proj, focalPoint);
163+
UiSettings uiSettings = new UiSettings(proj, focalPointInvalidator, compassView, attrView, logoView);
164+
TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPointInvalidator,
165+
zoomInvalidator);
166+
MyLocationViewSettings myLocationViewSettings = new MyLocationViewSettings(myLocationView, proj,
167+
focalPointInvalidator);
162168
LongSparseArray<Annotation> annotationsArray = new LongSparseArray<>();
163169
MarkerViewManager markerViewManager = new MarkerViewManager((ViewGroup) findViewById(R.id.markerViewContainer));
164170
IconManager iconManager = new IconManager(nativeMapView);
@@ -182,8 +188,9 @@ private void initialiseMap() {
182188
MapZoomControllerListener zoomListener = new MapZoomControllerListener(mapGestureDetector, uiSettings, transform);
183189
mapZoomButtonController.bind(uiSettings, zoomListener);
184190

191+
compassView.injectCompassAnimationListener(createCompassAnimationListener(cameraChangeDispatcher));
192+
compassView.setOnClickListener(createCompassClickListener(cameraChangeDispatcher));
185193
// inject widgets with MapboxMap
186-
compassView.setMapboxMap(mapboxMap);
187194
myLocationView.setMapboxMap(mapboxMap);
188195
attrView.setOnClickListener(new AttributionDialogManager(context, mapboxMap));
189196

@@ -205,6 +212,49 @@ private void initialiseMap() {
205212
}
206213
}
207214

215+
private FocalPointChangeListener createFocalPointChangeListener() {
216+
return new FocalPointChangeListener() {
217+
@Override
218+
public void onFocalPointChanged(PointF pointF) {
219+
focalPoint = pointF;
220+
}
221+
};
222+
}
223+
224+
private MapboxMap.OnCompassAnimationListener createCompassAnimationListener(final CameraChangeDispatcher
225+
cameraChangeDispatcher) {
226+
return new MapboxMap.OnCompassAnimationListener() {
227+
@Override
228+
public void onCompassAnimation() {
229+
cameraChangeDispatcher.onCameraMove();
230+
}
231+
232+
@Override
233+
public void onCompassAnimationFinished() {
234+
compassView.isAnimating(false);
235+
cameraChangeDispatcher.onCameraIdle();
236+
}
237+
};
238+
}
239+
240+
private OnClickListener createCompassClickListener(final CameraChangeDispatcher cameraChangeDispatcher) {
241+
return new OnClickListener() {
242+
@Override
243+
public void onClick(View v) {
244+
if (mapboxMap != null && compassView != null) {
245+
if (focalPoint != null) {
246+
mapboxMap.setFocalBearing(0, focalPoint.x, focalPoint.y, TIME_MAP_NORTH_ANIMATION);
247+
} else {
248+
mapboxMap.setFocalBearing(0, mapboxMap.getWidth() / 2, mapboxMap.getHeight() / 2, TIME_MAP_NORTH_ANIMATION);
249+
}
250+
cameraChangeDispatcher.onCameraMoveStarted(MapboxMap.OnCameraMoveStartedListener.REASON_API_ANIMATION);
251+
compassView.isAnimating(true);
252+
compassView.postDelayed(compassView, TIME_WAIT_IDLE + TIME_MAP_NORTH_ANIMATION);
253+
}
254+
}
255+
};
256+
}
257+
208258
//
209259
// Lifecycle events
210260
//

platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java

+17-1
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,9 @@ public double getMinZoomLevel() {
513513
* Sets the maximum zoom level the map can be displayed at.
514514
* </p>
515515
* <p>
516-
* The default maximum zoomn level is 22. The upper bound for this value is 25.5.
516+
* The default maximum zoomn level is 22. The upper bound for this value is 25.5.
517517
* </p>
518+
*
518519
* @param maxZoom The new maximum zoom level.
519520
*/
520521
public void setMaxZoomPreference(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM,
@@ -2081,6 +2082,21 @@ public interface OnCameraIdleListener {
20812082
void onCameraIdle();
20822083
}
20832084

2085+
/**
2086+
* Interface definition for a callback to be invoked for when the compass is animating.
2087+
*/
2088+
public interface OnCompassAnimationListener {
2089+
/**
2090+
* Called repeatedly as the compass continues to move after clicking on it.
2091+
*/
2092+
void onCompassAnimation();
2093+
2094+
/**
2095+
* Called when compass animation has ended.
2096+
*/
2097+
void onCompassAnimationFinished();
2098+
}
2099+
20842100
/**
20852101
* Interface definition for a callback to be invoked when a frame is rendered to the map view.
20862102
*

platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java

+17-46
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package com.mapbox.mapboxsdk.maps.widgets;
22

33
import android.content.Context;
4-
import android.graphics.PointF;
54
import android.graphics.drawable.Drawable;
65
import android.support.annotation.NonNull;
7-
import android.support.annotation.Nullable;
86
import android.support.v4.view.ViewCompat;
97
import android.support.v4.view.ViewPropertyAnimatorCompat;
108
import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
@@ -13,11 +11,8 @@
1311
import android.view.View;
1412
import android.view.ViewGroup;
1513

16-
import com.mapbox.mapboxsdk.maps.FocalPointChangeListener;
1714
import com.mapbox.mapboxsdk.maps.MapboxMap;
1815

19-
import java.lang.ref.WeakReference;
20-
2116
/**
2217
* UI element overlaid on a map to show the map's bearing when it isn't true north (0.0). Tapping
2318
* the compass resets the bearing to true north and hides the compass.
@@ -27,16 +22,17 @@
2722
* use {@link com.mapbox.mapboxsdk.maps.UiSettings}.
2823
* </p>
2924
*/
30-
public final class CompassView extends AppCompatImageView implements Runnable, FocalPointChangeListener {
25+
public final class CompassView extends AppCompatImageView implements Runnable {
3126

32-
private static final long TIME_WAIT_IDLE = 500;
27+
public static final long TIME_WAIT_IDLE = 500;
28+
public static final long TIME_MAP_NORTH_ANIMATION = 150;
3329
private static final long TIME_FADE_ANIMATION = TIME_WAIT_IDLE;
34-
private static final long TIME_MAP_NORTH_ANIMATION = 150;
3530

3631
private float rotation = 0.0f;
3732
private boolean fadeCompassViewFacingNorth = true;
3833
private ViewPropertyAnimatorCompat fadeAnimator;
39-
private PointF focalPoint;
34+
private MapboxMap.OnCompassAnimationListener compassAnimationListener;
35+
private boolean isAnimating = false;
4036

4137
public CompassView(Context context) {
4238
super(context);
@@ -62,9 +58,12 @@ private void initialize(Context context) {
6258
setLayoutParams(lp);
6359
}
6460

65-
// TODO refactor MapboxMap and replace with interface
66-
public void setMapboxMap(@NonNull MapboxMap mapboxMap) {
67-
setOnClickListener(new CompassClickListener(mapboxMap, this));
61+
public void injectCompassAnimationListener(@NonNull MapboxMap.OnCompassAnimationListener compassAnimationListener) {
62+
this.compassAnimationListener = compassAnimationListener;
63+
}
64+
65+
public void isAnimating(boolean isAnimating) {
66+
this.isAnimating = isAnimating;
6867
}
6968

7069
private void resetAnimation() {
@@ -97,11 +96,6 @@ public void setEnabled(boolean enabled) {
9796
}
9897
}
9998

100-
@Nullable
101-
PointF getFocalPoint() {
102-
return focalPoint;
103-
}
104-
10599
/**
106100
* Updates the direction of the compass.
107101
*
@@ -126,6 +120,7 @@ public void update(final double bearing) {
126120
setVisibility(View.VISIBLE);
127121
}
128122

123+
notifyCompassAnimationListenerWhenAnimating();
129124
setRotation(rotation);
130125
}
131126

@@ -157,7 +152,8 @@ public Drawable getCompassImage() {
157152

158153
@Override
159154
public void run() {
160-
if (isFacingNorth() && fadeCompassViewFacingNorth) {
155+
if (isHidden()) {
156+
compassAnimationListener.onCompassAnimationFinished();
161157
resetAnimation();
162158
setLayerType(View.LAYER_TYPE_HARDWARE, null);
163159
fadeAnimator = ViewCompat.animate(CompassView.this).alpha(0.0f).setDuration(TIME_FADE_ANIMATION);
@@ -172,34 +168,9 @@ public void onAnimationEnd(View view) {
172168
}
173169
}
174170

175-
@Override
176-
public void onFocalPointChanged(PointF pointF) {
177-
focalPoint = pointF;
178-
}
179-
180-
static class CompassClickListener implements View.OnClickListener {
181-
182-
private WeakReference<MapboxMap> mapboxMap;
183-
private WeakReference<CompassView> compassView;
184-
185-
CompassClickListener(final MapboxMap mapboxMap, CompassView compassView) {
186-
this.mapboxMap = new WeakReference<>(mapboxMap);
187-
this.compassView = new WeakReference<>(compassView);
188-
}
189-
190-
@Override
191-
public void onClick(View view) {
192-
final MapboxMap mapboxMap = this.mapboxMap.get();
193-
final CompassView compassView = this.compassView.get();
194-
if (mapboxMap != null && compassView != null) {
195-
PointF focalPoint = compassView.getFocalPoint();
196-
if (focalPoint != null) {
197-
mapboxMap.setFocalBearing(0, focalPoint.x, focalPoint.y, TIME_MAP_NORTH_ANIMATION);
198-
} else {
199-
mapboxMap.setFocalBearing(0, mapboxMap.getWidth() / 2, mapboxMap.getHeight() / 2, TIME_MAP_NORTH_ANIMATION);
200-
}
201-
compassView.postDelayed(compassView, TIME_WAIT_IDLE + TIME_MAP_NORTH_ANIMATION);
202-
}
171+
private void notifyCompassAnimationListenerWhenAnimating() {
172+
if (isAnimating) {
173+
compassAnimationListener.onCompassAnimation();
203174
}
204175
}
205176
}

0 commit comments

Comments
 (0)