[android] - zoom to at least 2 when tracking is enabled (#7795)
* [android] - zoom to at least 2 when tracking is enabled, introduce interface for zoom invalidation, simplify example * fixup unit test, added test for new interface + focal point interface
This commit is contained in:
@@ -132,10 +132,13 @@ public class MapView extends FrameLayout {
|
||||
// callback for registering touch listeners
|
||||
RegisterTouchListener registerTouchListener = new RegisterTouchListener();
|
||||
|
||||
// callback for zooming in the camera
|
||||
CameraZoomInvalidator zoomInvalidator = new CameraZoomInvalidator();
|
||||
|
||||
// setup components for MapboxMap creation
|
||||
Projection proj = new Projection(nativeMapView);
|
||||
UiSettings uiSettings = new UiSettings(proj, focalPoint, compassView, attrView, view.findViewById(R.id.logoView));
|
||||
TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPoint);
|
||||
TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPoint, zoomInvalidator);
|
||||
MyLocationViewSettings myLocationViewSettings = new MyLocationViewSettings(myLocationView, proj, focalPoint);
|
||||
MarkerViewManager markerViewManager = new MarkerViewManager((ViewGroup) findViewById(R.id.markerViewContainer));
|
||||
AnnotationManager annotations = new AnnotationManager(nativeMapView, this, markerViewManager);
|
||||
@@ -970,6 +973,16 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private class CameraZoomInvalidator implements TrackingSettings.CameraZoomInvalidator {
|
||||
@Override
|
||||
public void zoomTo(double zoomLevel) {
|
||||
double currentZoomLevel = mapboxMap.getCameraPosition().zoom;
|
||||
if (currentZoomLevel < zoomLevel) {
|
||||
mapboxMap.getTransform().setZoom(zoomLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MapCallback implements OnMapChangedListener {
|
||||
|
||||
private final MapboxMap mapboxMap;
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.PointF;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
@@ -28,6 +27,7 @@ public final class TrackingSettings {
|
||||
private final MyLocationView myLocationView;
|
||||
private final UiSettings uiSettings;
|
||||
private final FocalPointChangeListener focalPointChangedListener;
|
||||
private final CameraZoomInvalidator zoomInvalidator;
|
||||
private LocationListener myLocationListener;
|
||||
|
||||
private boolean myLocationEnabled;
|
||||
@@ -38,10 +38,11 @@ public final class TrackingSettings {
|
||||
private MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener;
|
||||
|
||||
TrackingSettings(@NonNull MyLocationView myLocationView, UiSettings uiSettings,
|
||||
FocalPointChangeListener focalPointChangedListener) {
|
||||
FocalPointChangeListener focalPointChangedListener, CameraZoomInvalidator zoomInvalidator) {
|
||||
this.myLocationView = myLocationView;
|
||||
this.focalPointChangedListener = focalPointChangedListener;
|
||||
this.uiSettings = uiSettings;
|
||||
this.zoomInvalidator = zoomInvalidator;
|
||||
}
|
||||
|
||||
void initialise(MapboxMapOptions options) {
|
||||
@@ -92,8 +93,8 @@ public final class TrackingSettings {
|
||||
myLocationView.setMyLocationTrackingMode(myLocationTrackingMode);
|
||||
|
||||
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
|
||||
focalPointChangedListener.onFocalPointChanged(new PointF(myLocationView.getCenterX(),
|
||||
myLocationView.getCenterY()));
|
||||
zoomInvalidator.zoomTo(2.0);
|
||||
focalPointChangedListener.onFocalPointChanged(myLocationView.getCenter());
|
||||
} else {
|
||||
focalPointChangedListener.onFocalPointChanged(null);
|
||||
}
|
||||
@@ -343,4 +344,8 @@ public final class TrackingSettings {
|
||||
void onStop() {
|
||||
myLocationView.onStop();
|
||||
}
|
||||
|
||||
interface CameraZoomInvalidator {
|
||||
void zoomTo(double zoomLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,6 +186,10 @@ final class Transform implements MapView.OnMapChangedListener {
|
||||
}
|
||||
}
|
||||
|
||||
void setZoom(double zoom) {
|
||||
mapView.setZoom(zoom);
|
||||
}
|
||||
|
||||
// Direction
|
||||
double getBearing() {
|
||||
double direction = -mapView.getBearing();
|
||||
|
||||
@@ -308,7 +308,7 @@ public class MyLocationView extends View {
|
||||
public void setTilt(@FloatRange(from = 0, to = 60.0f) double tilt) {
|
||||
this.tilt = tilt;
|
||||
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
|
||||
mapboxMap.getUiSettings().setFocalPoint(new PointF(getCenterX(), getCenterY()));
|
||||
mapboxMap.getUiSettings().setFocalPoint(getCenter());
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
@@ -529,11 +529,15 @@ public class MyLocationView extends View {
|
||||
directionAnimator.start();
|
||||
}
|
||||
|
||||
public float getCenterX() {
|
||||
public PointF getCenter() {
|
||||
return new PointF(getCenterX(), getCenterY());
|
||||
}
|
||||
|
||||
private float getCenterX() {
|
||||
return (getX() + getMeasuredWidth()) / 2 + contentPaddingX - projectedX;
|
||||
}
|
||||
|
||||
public float getCenterY() {
|
||||
private float getCenterY() {
|
||||
return (getY() + getMeasuredHeight()) / 2 + contentPaddingY - projectedY;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.mapbox.mapboxsdk.maps.widgets;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.IntRange;
|
||||
@@ -289,8 +288,7 @@ public class MyLocationViewSettings {
|
||||
|
||||
private void invalidateFocalPointForTracking(MyLocationView myLocationView) {
|
||||
if (!(myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE)) {
|
||||
focalPointChangeListener.onFocalPointChanged(new PointF(myLocationView.getCenterX(),
|
||||
myLocationView.getCenterY()));
|
||||
focalPointChangeListener.onFocalPointChanged(myLocationView.getCenter());
|
||||
} else {
|
||||
focalPointChangeListener.onFocalPointChanged(null);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.userlocation;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
@@ -21,11 +13,8 @@ import android.widget.ArrayAdapter;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.constants.MapboxConstants;
|
||||
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
|
||||
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
@@ -33,20 +22,19 @@ 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 {
|
||||
public class MyLocationTrackingModeActivity extends AppCompatActivity implements 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;
|
||||
@@ -91,8 +79,6 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity
|
||||
bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
|
||||
setCheckBoxes();
|
||||
|
||||
mapboxMap.setOnMyLocationChangeListener(MyLocationTrackingModeActivity.this);
|
||||
|
||||
mapboxMap.setOnMyLocationTrackingModeChangeListener(new MapboxMap.OnMyLocationTrackingModeChangeListener() {
|
||||
@Override
|
||||
public void onMyLocationTrackingModeChange(@MyLocationTracking.Mode int myLocationTrackingMode) {
|
||||
@@ -131,91 +117,12 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity
|
||||
});
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
toggleGps(true);
|
||||
mapboxMap.setMyLocationEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@UiThread
|
||||
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)) {
|
||||
ActivityCompat.requestPermissions(this, new String[] {
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
|
||||
} else {
|
||||
enableLocation(true);
|
||||
}
|
||||
} else {
|
||||
enableLocation(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void enableLocation(boolean enabled) {
|
||||
if (enabled) {
|
||||
mapboxMap.setMyLocationEnabled(true);
|
||||
Location location = mapboxMap.getMyLocation();
|
||||
if (location != null) {
|
||||
setInitialPosition(new LatLng(location));
|
||||
}
|
||||
} else {
|
||||
mapboxMap.setMyLocationEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
if (requestCode == PERMISSIONS_LOCATION) {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
enableLocation(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setInitialPosition(LatLng latLng) {
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14));
|
||||
mapboxMap.setMyLocationEnabled(true);
|
||||
locationSpinner.setEnabled(true);
|
||||
bearingSpinner.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMyLocationChange(@Nullable Location location) {
|
||||
if (location != null) {
|
||||
if (this.location == null) {
|
||||
// initial location to reposition map
|
||||
setInitialPosition(new LatLng(location));
|
||||
}
|
||||
this.location = location;
|
||||
showSnackBar();
|
||||
}
|
||||
}
|
||||
|
||||
private void showSnackBar() {
|
||||
String desc = "Loc Chg: ";
|
||||
boolean noInfo = true;
|
||||
if (location.hasSpeed()) {
|
||||
desc += String.format(MapboxConstants.MAPBOX_LOCALE, "Spd = %.1f km/h ", location.getSpeed() * 3.6f);
|
||||
noInfo = false;
|
||||
}
|
||||
if (location.hasAltitude()) {
|
||||
desc += String.format(MapboxConstants.MAPBOX_LOCALE, "Alt = %.0f m ", location.getAltitude());
|
||||
noInfo = false;
|
||||
}
|
||||
if (location.hasAccuracy()) {
|
||||
desc += String.format(MapboxConstants.MAPBOX_LOCALE, "Acc = %.0f m", location.getAccuracy());
|
||||
}
|
||||
|
||||
if (noInfo) {
|
||||
desc += "No extra info";
|
||||
}
|
||||
Snackbar.make(findViewById(android.R.id.content), desc, Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) throws SecurityException {
|
||||
TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.mapbox.mapboxsdk.maps;
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.PointF;
|
||||
|
||||
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
|
||||
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
|
||||
@@ -16,7 +17,9 @@ import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.atLeast;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class TrackingSettingsTest {
|
||||
@@ -30,11 +33,14 @@ public class TrackingSettingsTest {
|
||||
@InjectMocks
|
||||
FocalPointChangeListener focalPointChangeListener = mock(FocalPointChangeListener.class);
|
||||
|
||||
@InjectMocks
|
||||
TrackingSettings.CameraZoomInvalidator zoomInvalidator = mock(TrackingSettings.CameraZoomInvalidator.class);
|
||||
|
||||
private TrackingSettings trackingSettings;
|
||||
|
||||
@Before
|
||||
public void beforeTest() {
|
||||
trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPointChangeListener);
|
||||
trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPointChangeListener, zoomInvalidator);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -67,4 +73,27 @@ public class TrackingSettingsTest {
|
||||
trackingSettings.setMyLocationEnabled(true);
|
||||
assertTrue("Location should be enabled", trackingSettings.isMyLocationEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCameraZoomTo2forTracking() {
|
||||
trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
|
||||
verify(zoomInvalidator, atLeast(1)).zoomTo(2.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFocalPointChangeForTracking() {
|
||||
final float centerX = 32.3f;
|
||||
final float centerY = 46.3f;
|
||||
final PointF pointF = new PointF(centerX, centerY);
|
||||
when(myLocationView.getCenter()).thenReturn(pointF);
|
||||
|
||||
trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
|
||||
verify(focalPointChangeListener, atLeast(1)).onFocalPointChanged(pointF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFocalPointChangeForNonTracking() {
|
||||
trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
|
||||
verify(focalPointChangeListener, atLeast(1)).onFocalPointChanged(null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user