[android] hook camera events into compass (#10019)

This commit is contained in:
Pablo Guardiola
2017-09-20 10:15:56 +02:00
committed by GitHub
parent 53d072cbf5
commit 2fcbd78062
3 changed files with 90 additions and 53 deletions

View File

@@ -47,6 +47,9 @@ import java.util.concurrent.CopyOnWriteArrayList;
import timber.log.Timber;
import static com.mapbox.mapboxsdk.maps.widgets.CompassView.TIME_MAP_NORTH_ANIMATION;
import static com.mapbox.mapboxsdk.maps.widgets.CompassView.TIME_WAIT_IDLE;
/**
* <p>
* A {@code MapView} provides an embeddable map interface.
@@ -73,6 +76,7 @@ public class MapView extends FrameLayout {
private MyLocationView myLocationView;
private CompassView compassView;
private PointF focalPoint;
private ImageView attrView;
private ImageView logoView;
@@ -143,7 +147,7 @@ public class MapView extends FrameLayout {
addOnMapChangedListener(mapCallback);
// callback for focal point invalidation
FocalPointInvalidator focalPoint = new FocalPointInvalidator(compassView);
final FocalPointInvalidator focalPointInvalidator = new FocalPointInvalidator(createFocalPointChangeListener());
// callback for registering touch listeners
RegisterTouchListener registerTouchListener = new RegisterTouchListener();
@@ -152,13 +156,15 @@ public class MapView extends FrameLayout {
CameraZoomInvalidator zoomInvalidator = new CameraZoomInvalidator();
// callback for camera change events
CameraChangeDispatcher cameraChangeDispatcher = new CameraChangeDispatcher();
final CameraChangeDispatcher cameraChangeDispatcher = new CameraChangeDispatcher();
// setup components for MapboxMap creation
Projection proj = new Projection(nativeMapView);
UiSettings uiSettings = new UiSettings(proj, focalPoint, compassView, attrView, logoView);
TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPoint, zoomInvalidator);
MyLocationViewSettings myLocationViewSettings = new MyLocationViewSettings(myLocationView, proj, focalPoint);
UiSettings uiSettings = new UiSettings(proj, focalPointInvalidator, compassView, attrView, logoView);
TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPointInvalidator,
zoomInvalidator);
MyLocationViewSettings myLocationViewSettings = new MyLocationViewSettings(myLocationView, proj,
focalPointInvalidator);
LongSparseArray<Annotation> annotationsArray = new LongSparseArray<>();
MarkerViewManager markerViewManager = new MarkerViewManager((ViewGroup) findViewById(R.id.markerViewContainer));
IconManager iconManager = new IconManager(nativeMapView);
@@ -182,8 +188,9 @@ public class MapView extends FrameLayout {
MapZoomControllerListener zoomListener = new MapZoomControllerListener(mapGestureDetector, uiSettings, transform);
mapZoomButtonController.bind(uiSettings, zoomListener);
compassView.injectCompassAnimationListener(createCompassAnimationListener(cameraChangeDispatcher));
compassView.setOnClickListener(createCompassClickListener(cameraChangeDispatcher));
// inject widgets with MapboxMap
compassView.setMapboxMap(mapboxMap);
myLocationView.setMapboxMap(mapboxMap);
attrView.setOnClickListener(new AttributionDialogManager(context, mapboxMap));
@@ -205,6 +212,49 @@ public class MapView extends FrameLayout {
}
}
private FocalPointChangeListener createFocalPointChangeListener() {
return new FocalPointChangeListener() {
@Override
public void onFocalPointChanged(PointF pointF) {
focalPoint = pointF;
}
};
}
private MapboxMap.OnCompassAnimationListener createCompassAnimationListener(final CameraChangeDispatcher
cameraChangeDispatcher) {
return new MapboxMap.OnCompassAnimationListener() {
@Override
public void onCompassAnimation() {
cameraChangeDispatcher.onCameraMove();
}
@Override
public void onCompassAnimationFinished() {
compassView.isAnimating(false);
cameraChangeDispatcher.onCameraIdle();
}
};
}
private OnClickListener createCompassClickListener(final CameraChangeDispatcher cameraChangeDispatcher) {
return new OnClickListener() {
@Override
public void onClick(View v) {
if (mapboxMap != null && compassView != null) {
if (focalPoint != null) {
mapboxMap.setFocalBearing(0, focalPoint.x, focalPoint.y, TIME_MAP_NORTH_ANIMATION);
} else {
mapboxMap.setFocalBearing(0, mapboxMap.getWidth() / 2, mapboxMap.getHeight() / 2, TIME_MAP_NORTH_ANIMATION);
}
cameraChangeDispatcher.onCameraMoveStarted(MapboxMap.OnCameraMoveStartedListener.REASON_API_ANIMATION);
compassView.isAnimating(true);
compassView.postDelayed(compassView, TIME_WAIT_IDLE + TIME_MAP_NORTH_ANIMATION);
}
}
};
}
//
// Lifecycle events
//

View File

@@ -513,8 +513,9 @@ public final class MapboxMap {
* Sets the maximum zoom level the map can be displayed at.
* </p>
* <p>
* The default maximum zoomn level is 22. The upper bound for this value is 25.5.
* The default maximum zoomn level is 22. The upper bound for this value is 25.5.
* </p>
*
* @param maxZoom The new maximum zoom level.
*/
public void setMaxZoomPreference(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM,
@@ -2081,6 +2082,21 @@ public final class MapboxMap {
void onCameraIdle();
}
/**
* Interface definition for a callback to be invoked for when the compass is animating.
*/
public interface OnCompassAnimationListener {
/**
* Called repeatedly as the compass continues to move after clicking on it.
*/
void onCompassAnimation();
/**
* Called when compass animation has ended.
*/
void onCompassAnimationFinished();
}
/**
* Interface definition for a callback to be invoked when a frame is rendered to the map view.
*

View File

@@ -1,10 +1,8 @@
package com.mapbox.mapboxsdk.maps.widgets;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPropertyAnimatorCompat;
import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
@@ -13,11 +11,8 @@ import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import com.mapbox.mapboxsdk.maps.FocalPointChangeListener;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import java.lang.ref.WeakReference;
/**
* UI element overlaid on a map to show the map's bearing when it isn't true north (0.0). Tapping
* the compass resets the bearing to true north and hides the compass.
@@ -27,16 +22,17 @@ import java.lang.ref.WeakReference;
* use {@link com.mapbox.mapboxsdk.maps.UiSettings}.
* </p>
*/
public final class CompassView extends AppCompatImageView implements Runnable, FocalPointChangeListener {
public final class CompassView extends AppCompatImageView implements Runnable {
private static final long TIME_WAIT_IDLE = 500;
public static final long TIME_WAIT_IDLE = 500;
public static final long TIME_MAP_NORTH_ANIMATION = 150;
private static final long TIME_FADE_ANIMATION = TIME_WAIT_IDLE;
private static final long TIME_MAP_NORTH_ANIMATION = 150;
private float rotation = 0.0f;
private boolean fadeCompassViewFacingNorth = true;
private ViewPropertyAnimatorCompat fadeAnimator;
private PointF focalPoint;
private MapboxMap.OnCompassAnimationListener compassAnimationListener;
private boolean isAnimating = false;
public CompassView(Context context) {
super(context);
@@ -62,9 +58,12 @@ public final class CompassView extends AppCompatImageView implements Runnable, F
setLayoutParams(lp);
}
// TODO refactor MapboxMap and replace with interface
public void setMapboxMap(@NonNull MapboxMap mapboxMap) {
setOnClickListener(new CompassClickListener(mapboxMap, this));
public void injectCompassAnimationListener(@NonNull MapboxMap.OnCompassAnimationListener compassAnimationListener) {
this.compassAnimationListener = compassAnimationListener;
}
public void isAnimating(boolean isAnimating) {
this.isAnimating = isAnimating;
}
private void resetAnimation() {
@@ -97,11 +96,6 @@ public final class CompassView extends AppCompatImageView implements Runnable, F
}
}
@Nullable
PointF getFocalPoint() {
return focalPoint;
}
/**
* Updates the direction of the compass.
*
@@ -126,6 +120,7 @@ public final class CompassView extends AppCompatImageView implements Runnable, F
setVisibility(View.VISIBLE);
}
notifyCompassAnimationListenerWhenAnimating();
setRotation(rotation);
}
@@ -157,7 +152,8 @@ public final class CompassView extends AppCompatImageView implements Runnable, F
@Override
public void run() {
if (isFacingNorth() && fadeCompassViewFacingNorth) {
if (isHidden()) {
compassAnimationListener.onCompassAnimationFinished();
resetAnimation();
setLayerType(View.LAYER_TYPE_HARDWARE, null);
fadeAnimator = ViewCompat.animate(CompassView.this).alpha(0.0f).setDuration(TIME_FADE_ANIMATION);
@@ -172,34 +168,9 @@ public final class CompassView extends AppCompatImageView implements Runnable, F
}
}
@Override
public void onFocalPointChanged(PointF pointF) {
focalPoint = pointF;
}
static class CompassClickListener implements View.OnClickListener {
private WeakReference<MapboxMap> mapboxMap;
private WeakReference<CompassView> compassView;
CompassClickListener(final MapboxMap mapboxMap, CompassView compassView) {
this.mapboxMap = new WeakReference<>(mapboxMap);
this.compassView = new WeakReference<>(compassView);
}
@Override
public void onClick(View view) {
final MapboxMap mapboxMap = this.mapboxMap.get();
final CompassView compassView = this.compassView.get();
if (mapboxMap != null && compassView != null) {
PointF focalPoint = compassView.getFocalPoint();
if (focalPoint != null) {
mapboxMap.setFocalBearing(0, focalPoint.x, focalPoint.y, TIME_MAP_NORTH_ANIMATION);
} else {
mapboxMap.setFocalBearing(0, mapboxMap.getWidth() / 2, mapboxMap.getHeight() / 2, TIME_MAP_NORTH_ANIMATION);
}
compassView.postDelayed(compassView, TIME_WAIT_IDLE + TIME_MAP_NORTH_ANIMATION);
}
private void notifyCompassAnimationListenerWhenAnimating() {
if (isAnimating) {
compassAnimationListener.onCompassAnimation();
}
}
}