[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:
Tobrun
2017-01-23 17:51:09 +01:00
committed by GitHub
parent 91efbc36a2
commit fbe0320c9c
7 changed files with 69 additions and 109 deletions

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -186,6 +186,10 @@ final class Transform implements MapView.OnMapChangedListener {
}
}
void setZoom(double zoom) {
mapView.setZoom(zoom);
}
// Direction
double getBearing() {
double direction = -mapView.getBearing();

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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);
}
}