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

Android Tilt Implementation #3158

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
36eb07a
[android] #2805 - Initial CameraPosition API
bleege Nov 30, 2015
339f806
[android] #2805 - Implementing Parcelable and adding Builder
bleege Dec 1, 2015
645e9ee
[android] #2805 - add sample tilt activity to test app
zugaldia Dec 1, 2015
d289f23
[android] #2805 - Adding Toolbar to TiltActivity for consistent navig…
bleege Dec 2, 2015
48f8bbf
[android] #2805 - CameraUpdate and animateCamera() API
bleege Dec 2, 2015
556ea6f
[android] #2805 - Adding processing of target, zoom, and bearing in a…
bleege Dec 2, 2015
b23caa7
[android] #2805 - Basic wiring up of Android Tilt methods to Core GL …
bleege Dec 3, 2015
f22c5f1
[android] #2805 - Create a target to keep both location values consis…
zugaldia Dec 3, 2015
4567d7d
[android] #2805 - Setting TiltActivity to test setPitch() directly. …
bleege Dec 3, 2015
3ce3656
[android] #2805 - Placeholder for a ShoveGestureListener
zugaldia Dec 3, 2015
038318c
[android] #2805 - public API to enable or disable tilt
zugaldia Dec 3, 2015
bd5bb94
[android] #2805 - add mShoveGestureDetector to the event chain
zugaldia Dec 3, 2015
57705ac
[android] #2805 - Updating Tilt API to support animation duration time
bleege Dec 3, 2015
56a4f57
[android] #2805 - basic tilt gesture working with ShoveGestureListener
zugaldia Dec 3, 2015
17cdc1c
Merge remote-tracking branch 'origin/2805-android-tilt' into 2805-and…
bleege Dec 3, 2015
9f8acf5
[android] #2805 - Integrating gesture with new get / set Tilt API ref…
bleege Dec 3, 2015
eede504
[android] #2805 - Removing Camera API for now
bleege Dec 3, 2015
ddf3a4b
[android] #2805 - scale and clamp values for pitch
zugaldia Dec 3, 2015
b20f5db
[android] #2805 - scale and clamp values for pitch
zugaldia Dec 3, 2015
4ac5f3d
[android] #2805 - Using MINIMUM_TILT and MAXIMUM_TILT constants for a…
bleege Dec 3, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ZoomButtonsController;

import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector;
import com.almeros.android.multitouch.gesturedetectors.ShoveGestureDetector;
import com.almeros.android.multitouch.gesturedetectors.TwoFingerGestureDetector;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.annotations.Annotation;
Expand Down Expand Up @@ -118,6 +118,7 @@ public final class MapView extends FrameLayout {
private static final String STATE_ZOOM_ENABLED = "zoomEnabled";
private static final String STATE_SCROLL_ENABLED = "scrollEnabled";
private static final String STATE_ROTATE_ENABLED = "rotateEnabled";
private static final String STATE_TILT_ENABLED = "tiltEnabled";
private static final String STATE_ZOOM_CONTROLS_ENABLED = "zoomControlsEnabled";
private static final String STATE_DEBUG_ACTIVE = "debugActive";
private static final String STATE_STYLE_URL = "styleUrl";
Expand Down Expand Up @@ -162,6 +163,14 @@ public final class MapView extends FrameLayout {
*/
public static final double MAXIMUM_ZOOM_LEVEL = 18.0;

/**
* The currently supported maximum and minimum tilt values.
*
* @see MapView#setTilt(double)
*/
private static final double MINIMUM_TILT = 0;
private static final double MAXIMUM_TILT = 60;

//
// Instance members
//
Expand All @@ -179,6 +188,7 @@ public final class MapView extends FrameLayout {
private GestureDetectorCompat mGestureDetector;
private ScaleGestureDetector mScaleGestureDetector;
private RotateGestureDetector mRotateGestureDetector;
private ShoveGestureDetector mShoveGestureDetector;
private boolean mTwoTap = false;
private boolean mZoomStarted = false;
private boolean mQuickZoom = false;
Expand Down Expand Up @@ -241,6 +251,7 @@ public final class MapView extends FrameLayout {
private boolean mZoomEnabled = true;
private boolean mScrollEnabled = true;
private boolean mRotateEnabled = true;
private boolean mTiltEnabled = true;
private boolean mAllowConcurrentMultipleOpenInfoWindows = false;
private String mStyleUrl;

Expand Down Expand Up @@ -681,6 +692,7 @@ private void initialize(Context context, AttributeSet attrs) {
mScaleGestureDetector = new ScaleGestureDetector(context, new ScaleGestureListener());
ScaleGestureDetectorCompat.setQuickScaleEnabled(mScaleGestureDetector, true);
mRotateGestureDetector = new RotateGestureDetector(context, new RotateGestureListener());
mShoveGestureDetector = new ShoveGestureDetector(context, new ShoveGestureListener());

// Shows the zoom controls
if (!context.getPackageManager()
Expand Down Expand Up @@ -726,6 +738,7 @@ private void initialize(Context context, AttributeSet attrs) {
setZoomEnabled(typedArray.getBoolean(R.styleable.MapView_zoom_enabled, true));
setScrollEnabled(typedArray.getBoolean(R.styleable.MapView_scroll_enabled, true));
setRotateEnabled(typedArray.getBoolean(R.styleable.MapView_rotate_enabled, true));
setTiltEnabled(typedArray.getBoolean(R.styleable.MapView_tilt_enabled, true));
setZoomControlsEnabled(typedArray.getBoolean(R.styleable.MapView_zoom_controls_enabled, isZoomControlsEnabled()));
setDebugActive(typedArray.getBoolean(R.styleable.MapView_debug_active, false));
if (typedArray.getString(R.styleable.MapView_style_url) != null) {
Expand Down Expand Up @@ -801,6 +814,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
setZoomEnabled(savedInstanceState.getBoolean(STATE_ZOOM_ENABLED));
setScrollEnabled(savedInstanceState.getBoolean(STATE_SCROLL_ENABLED));
setRotateEnabled(savedInstanceState.getBoolean(STATE_ROTATE_ENABLED));
setTiltEnabled(savedInstanceState.getBoolean(STATE_TILT_ENABLED));
setZoomControlsEnabled(savedInstanceState.getBoolean(STATE_ZOOM_CONTROLS_ENABLED));
setDebugActive(savedInstanceState.getBoolean(STATE_DEBUG_ACTIVE));
setStyleUrl(savedInstanceState.getString(STATE_STYLE_URL));
Expand Down Expand Up @@ -881,6 +895,7 @@ public void onSaveInstanceState(@NonNull Bundle outState) {
outState.putBoolean(STATE_ZOOM_ENABLED, isZoomEnabled());
outState.putBoolean(STATE_SCROLL_ENABLED, isScrollEnabled());
outState.putBoolean(STATE_ROTATE_ENABLED, isRotateEnabled());
outState.putBoolean(STATE_TILT_ENABLED, isTiltEnabled());
outState.putBoolean(STATE_ZOOM_CONTROLS_ENABLED, isZoomControlsEnabled());
outState.putBoolean(STATE_DEBUG_ACTIVE, isDebugActive());
outState.putString(STATE_STYLE_URL, getStyleUrl());
Expand Down Expand Up @@ -1101,6 +1116,32 @@ public void setScrollEnabled(boolean scrollEnabled) {
this.mScrollEnabled = scrollEnabled;
}

//
// Pitch / Tilt
//

/**
* Gets the current Tilt in degrees of the MapView
* @return tilt in degrees
*/
public double getTilt() {
return mNativeMapView.getPitch();
}

/**
* Sets the Tilt in degrees of the MapView.
* @param pitch New tilt in degrees
* @param duration Animation time in milliseconds. If null then 0 is used, making the animation immediate.
*/
@FloatRange(from = MINIMUM_TILT, to = MAXIMUM_TILT)
public void setTilt(Double pitch, @Nullable Long duration) {
long actualDuration = 0;
if (duration != null) {
actualDuration = duration;
}
mNativeMapView.setPitch(pitch, actualDuration);
}

//
// Rotation
//
Expand Down Expand Up @@ -1335,6 +1376,35 @@ private void zoom(boolean zoomIn, float x, float y) {
}
}

//
// Tilt
//

/**
* Returns whether the user may tilt the map.
*
* @return If true, tilting is enabled.
*/
@UiThread
public boolean isTiltEnabled() {
return mTiltEnabled;
}

/**
* Changes whether the user may tilt the map.
* <p/>
* This setting controls only user interactions with the map. If you set the value to false,
* you may still change the map location programmatically.
* <p/>
* The default value is true.
*
* @param tiltEnabled If true, tilting is enabled.
*/
@UiThread
public void setTiltEnabled(boolean tiltEnabled) {
this.mTiltEnabled = tiltEnabled;
}

//
// InfoWindows
//
Expand Down Expand Up @@ -2380,11 +2450,13 @@ protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
* @see MapView#setZoomEnabled(boolean)
* @see MapView#setScrollEnabled(boolean)
* @see MapView#setRotateEnabled(boolean)
* @see MapView#setTiltEnabled(boolean)
*/
public void setAllGesturesEnabled(boolean enabled) {
setZoomEnabled(enabled);
setScrollEnabled(enabled);
setRotateEnabled(enabled);
setTiltEnabled(enabled);
}

// Called when user touches the screen, all positions are absolute
Expand All @@ -2399,6 +2471,7 @@ public boolean onTouchEvent(@NonNull MotionEvent event) {
// Check two finger gestures first
mRotateGestureDetector.onTouchEvent(event);
mScaleGestureDetector.onTouchEvent(event);
mShoveGestureDetector.onTouchEvent(event);

// Handle two finger tap
switch (event.getActionMasked()) {
Expand All @@ -2420,7 +2493,9 @@ public boolean onTouchEvent(@NonNull MotionEvent event) {
// First pointer up
long tapInterval = event.getEventTime() - event.getDownTime();
boolean isTap = tapInterval <= ViewConfiguration.getTapTimeout();
boolean inProgress = mRotateGestureDetector.isInProgress() || mScaleGestureDetector.isInProgress();
boolean inProgress = mRotateGestureDetector.isInProgress()
|| mScaleGestureDetector.isInProgress()
|| mShoveGestureDetector.isInProgress();

if (mTwoTap && isTap && !inProgress) {
PointF focalPoint = TwoFingerGestureDetector.determineFocalPoint(event);
Expand Down Expand Up @@ -2789,6 +2864,71 @@ public boolean onRotate(RotateGestureDetector detector) {
}
}

// This class handles a vertical two-finger shove. (If you place two fingers on screen with
// less than a 20 degree angle between them, this will detect movement on the Y-axis.)
private class ShoveGestureListener implements ShoveGestureDetector.OnShoveGestureListener {

long mBeginTime = 0;
float mTotalDelta = 0.0f;
boolean mStarted = false;

@Override
public boolean onShoveBegin(ShoveGestureDetector detector) {
if (!mTiltEnabled) {
return false;
}

mBeginTime = detector.getEventTime();
return true;
}

@Override
public void onShoveEnd(ShoveGestureDetector detector) {
mBeginTime = 0;
mTotalDelta = 0.0f;
mStarted = false;
}

@Override
public boolean onShove(ShoveGestureDetector detector) {
if (!mTiltEnabled) {
return false;
}

// If tilt is large enough ignore a tap
// Also if zoom already started, don't tilt
mTotalDelta += detector.getShovePixelsDelta();
if (!mZoomStarted && ((mTotalDelta > 10.0f) || (mTotalDelta < -10.0f))) {
mStarted = true;
}

// Ignore short touches in case it is a tap
// Also ignore small tilt
long time = detector.getEventTime();
long interval = time - mBeginTime;
if (!mStarted && (interval <= ViewConfiguration.getTapTimeout())) {
return false;
}

if (!mStarted) {
return false;
}

// Cancel any animation
mNativeMapView.cancelTransitions();

// Get tilt value (scale and clamp)
double pitch = mNativeMapView.getPitch();
pitch += 0.1 * detector.getShovePixelsDelta();
pitch = Math.max(MINIMUM_TILT, Math.min(MAXIMUM_TILT, pitch));

// Tilt the map
setTilt(pitch, null);

return true;
}
}

// This class handles input events from the zoom control buttons
// Zoom controls allow single touch only devices to zoom in and out
private class OnZoomListener implements ZoomButtonsController.OnZoomListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,14 @@ public void resetPosition() {
nativeResetPosition(mNativeMapViewPtr);
}

public double getPitch() {
return nativeGetPitch(mNativeMapViewPtr);
}

public void setPitch(double pitch, long duration) {
nativeSetPitch(mNativeMapViewPtr, pitch, duration);
}

public void scaleBy(double ds) {
scaleBy(ds, -1.0, -1.0);
}
Expand Down Expand Up @@ -533,6 +541,10 @@ private native void nativeSetLatLng(long nativeMapViewPtr, LatLng latLng,

private native void nativeResetPosition(long nativeMapViewPtr);

private native double nativeGetPitch(long nativeMapViewPtr);

private native void nativeSetPitch(long nativeMapViewPtr, double pitch, long duration);

private native void nativeScaleBy(long nativeMapViewPtr, double ds,
double cx, double cy, long duration);

Expand Down
1 change: 1 addition & 0 deletions android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<attr name="zoom_enabled" format="boolean" />
<attr name="scroll_enabled" format="boolean" />
<attr name="rotate_enabled" format="boolean" />
<attr name="tilt_enabled" format="boolean" />
<attr name="zoom_controls_enabled" format="boolean" />
<attr name="debug_active" format="boolean" />
<attr name="style_url" format="string" />
Expand Down
19 changes: 6 additions & 13 deletions android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<activity
android:name=".MainActivity"
android:label="@string/app_name">
Expand All @@ -23,47 +22,41 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".VisibleCoordinateBoundsActivity"
android:label="@string/activity_visible_coordinate_bounds" />

<activity
android:name=".InfoWindowAdapterActivity"
android:label="@string/activity_infowindow_adapter" />

<activity
android:name=".InfoWindowActivity"
android:label="@string/activity_info_window" />

<activity
android:name=".BulkMarkerActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/action_add_bulk_markers" />

<activity
android:name=".TiltActivity"
android:label="@string/activity_tilt" />
<activity
android:name=".MapFragmentActivity"
android:label="@string/activity_map_fragment" />

<activity
android:name=".PressForMarkerActivity"
android:label="@string/activity_press_for_marker" />

<activity android:name=".ManualZoomActivity"
android:label="@string/action_manual_zoom"/>

<activity
android:name=".ManualZoomActivity"
android:label="@string/action_manual_zoom" />
<activity
android:name=".MyLocationTrackingModeActivity"
android:label="@string/activity_user_tracking_mode" />

<activity
android:name=".PolylineActivity"
android:label="@string/activity_polyline" />

<meta-data
android:name="io.fabric.ApiKey"
android:value="9724157045ff7d083492c6d9ae03e60e8609d461" />

<meta-data
android:name="com.mapbox.AccessToken"
android:value="" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,10 @@ public boolean onNavigationItemSelected(MenuItem menuItem) {
startActivity(new Intent(getApplicationContext(), InfoWindowAdapterActivity.class));
return true;

case R.id.action_tilt:
startActivity(new Intent(getApplicationContext(), TiltActivity.class));
return true;

case R.id.action_map_fragment:
startActivity(new Intent(getApplicationContext(), MapFragmentActivity.class));
return true;
Expand Down
Loading