summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobrun <tobrun@mapbox.com>2016-02-03 14:51:22 +0100
committerTobrun <tobrun@mapbox.com>2016-02-03 18:38:38 +0100
commit9beb6629b68f2c07ff3f778d9bf4acfbcb3b6598 (patch)
tree29fc804149188b643ff3ace322578a59d3d6808c
parent37c27f3a8f55ae74d7da9b5f45fa577de3af7f21 (diff)
downloadqtlocation-mapboxgl-9beb6629b68f2c07ff3f778d9bf4acfbcb3b6598.tar.gz
[android] #3752 - added scroll by x,y feature, introduced new CameraUpdateType, introduced caching system for invalidating CameraPosition, general cleanup, readded getLatLng in MapView, ..
[android] #3752 - correctly invalidating cameraposition
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java40
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java68
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java15
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java36
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml6
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ScrollByActivity.java166
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_input_24dp.xml9
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_scroll_by.xml99
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml17
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml4
11 files changed, 422 insertions, 42 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
index 1b7bcba32e..004e7f5f84 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
@@ -81,6 +81,11 @@ public final class CameraPosition implements Parcelable {
}
@Override
+ public String toString() {
+ return "Target: " + target + ", Zoom:" + zoom + ", Bearing:" + bearing + ", Tilt:" + tilt;
+ }
+
+ @Override
public boolean equals(Object o) {
if (this == o) {
return true;
@@ -119,6 +124,7 @@ public final class CameraPosition implements Parcelable {
private LatLng target = null;
private float tilt = -1;
private float zoom = -1;
+ private boolean isRadiant;
/**
* Creates an empty builder.
@@ -128,6 +134,15 @@ public final class CameraPosition implements Parcelable {
}
/**
+ * Creates a builder for building CameraPosition objects using radiants.
+ *
+ * @param isRadiant
+ */
+ public Builder(boolean isRadiant) {
+ this.isRadiant = isRadiant;
+ }
+
+ /**
* Create Builder with an existing CameraPosition data.
*
* @param previous Existing CameraPosition values to use
@@ -147,13 +162,13 @@ public final class CameraPosition implements Parcelable {
*
* @param typedArray TypedArray containgin attribute values
*/
- public Builder(TypedArray typedArray){
+ public Builder(TypedArray typedArray) {
super();
- if(typedArray!=null) {
+ if (typedArray != null) {
this.bearing = typedArray.getFloat(R.styleable.MapView_direction, 0.0f);
double lat = typedArray.getFloat(R.styleable.MapView_center_latitude, 0.0f);
double lng = typedArray.getFloat(R.styleable.MapView_center_longitude, 0.0f);
- this.target= new LatLng(lat, lng);
+ this.target = new LatLng(lat, lng);
this.tilt = typedArray.getFloat(R.styleable.MapView_tilt, 0.0f);
this.zoom = typedArray.getFloat(R.styleable.MapView_zoom, 0.0f);
}
@@ -174,15 +189,14 @@ public final class CameraPosition implements Parcelable {
}
}
-
/**
* Create Builder from an existing CameraPositionUpdate update.
*
* @param update Update containing camera options
*/
- public Builder(CameraUpdateFactory.ZoomUpdate update){
+ public Builder(CameraUpdateFactory.ZoomUpdate update) {
super();
- if(update!=null){
+ if (update != null) {
this.zoom = update.getZoom();
}
}
@@ -194,7 +208,12 @@ public final class CameraPosition implements Parcelable {
* @return Builder
*/
public Builder bearing(float bearing) {
- this.bearing = (float) (-bearing * MathConstants.DEG2RAD);
+ if(isRadiant){
+ this.bearing = bearing;
+ }else{
+ // converting degrees to radiant
+ this.bearing = (float) (-bearing * MathConstants.DEG2RAD);
+ }
return this;
}
@@ -226,7 +245,12 @@ public final class CameraPosition implements Parcelable {
*/
@FloatRange(from = 0.0, to = 60.0)
public Builder tilt(float tilt) {
- this.tilt = (float) (MathUtils.clamp(tilt, MapboxConstants.MINIMUM_TILT, MapboxConstants.MAXIMUM_TILT) * MathConstants.DEG2RAD);
+ if(isRadiant){
+ this.tilt = tilt;
+ }else {
+ // converting degrees to radiant
+ this.tilt = (float) (MathUtils.clamp(tilt, MapboxConstants.MINIMUM_TILT, MapboxConstants.MAXIMUM_TILT) * MathConstants.DEG2RAD);
+ }
return this;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java
index 38b340908a..81b4556076 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java
@@ -69,22 +69,6 @@ public class CameraUpdateFactory {
return new CameraBoundsUpdate(bounds, paddingLeft, paddingTop, paddingRight, paddingBottom);
}
-// /**
-// * Returns a CameraUpdate that transforms the camera such that the specified latitude/longitude
-// * bounds are centered on screen within a bounding box of specified dimensions at the greatest
-// * possible zoom level. You can specify additional padding, to further restrict the size of
-// * the bounding box. The returned CameraUpdate has a bearing of 0 and a tilt of 0.
-// *
-// * @param bounds
-// * @param width
-// * @param height
-// * @param padding
-// * @return
-// */
-// public static CameraUpdate newLatLngBounds(@NonNull LatLngBounds bounds, int width, int height, int padding) {
-// throw new UnsupportedOperationException("Not implemented yet");
-// }
-
/**
* Returns a CameraUpdate that moves the center of the screen to a latitude and longitude specified by a LatLng object, and moves to the given zoom level.
*
@@ -96,16 +80,16 @@ public class CameraUpdateFactory {
return new CameraPositionUpdate(-1, latLng, -1, zoom);
}
-// /**
-// * Returns a CameraUpdate that scrolls the camera over the map, shifting the center of view by the specified number of pixels in the x and y directions.
-// *
-// * @param xPixel
-// * @param yPixel
-// * @return
-// */
-// public static CameraUpdate scrollBy(float xPixel, float yPixel) {
-// throw new UnsupportedOperationException("Not implemented yet");
-// }
+ /**
+ * Returns a CameraUpdate that scrolls the camera over the map, shifting the center of view by the specified number of pixels in the x and y directions.
+ *
+ * @param xPixel
+ * @param yPixel
+ * @return
+ */
+ public static CameraUpdate scrollBy(float xPixel, float yPixel) {
+ return new CameraMoveUpdate(xPixel, yPixel);
+ }
/**
* Returns a CameraUpdate that shifts the zoom level of the current camera viewpoint.
@@ -267,6 +251,38 @@ public class CameraUpdateFactory {
}
}
+ public static class CameraMoveUpdate implements CameraUpdate {
+
+ private float x;
+ private float y;
+
+ public CameraMoveUpdate(float x, float y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ @Override
+ public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
+ MapView mapView = mapboxMap.getMapView();
+
+ // Calculate the new center point
+ float viewPortWidth = mapView.getWidth();
+ float viewPortHeight = mapView.getHeight();
+ PointF targetPoint = new PointF(viewPortWidth / 2 + x, viewPortHeight / 2 + y);
+
+ // Convert point to LatLng
+ LatLng latLng = mapView.fromScreenLocation(targetPoint);
+
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ return new CameraPosition.Builder()
+ .target(latLng)
+ .zoom(cameraPosition.zoom)
+ .tilt(cameraPosition.tilt)
+ .bearing(cameraPosition.bearing)
+ .build();
+ }
+ }
+
public static class ZoomUpdate implements CameraUpdate {
@IntDef({ZOOM_IN, ZOOM_OUT, ZOOM_BY, ZOOM_TO, ZOOM_TO_POINT})
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
index a9fe3a7994..38db55ea53 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
@@ -160,10 +160,10 @@ public class MapView extends FrameLayout {
}
private void initialize(@NonNull Context context, @Nullable AttributeSet attrs) {
+ mOnMapChangedListener = new ArrayList<>();
mMapboxMap = new MapboxMap(this);
mAnnotations = new ArrayList<>();
mIcons = new ArrayList<>();
- mOnMapChangedListener = new ArrayList<>();
View view = LayoutInflater.from(context).inflate(R.layout.mapview_internal, this);
@@ -513,6 +513,19 @@ public class MapView extends FrameLayout {
}
//
+ // LatLng / CenterCoordinate
+ //
+
+ /**
+ * Gets the current LatLng in the center of the MapView
+ *
+ * @return The center in LatLng
+ */
+ LatLng getLatLng() {
+ return mNativeMapView.getLatLng();
+ }
+
+ //
// Pitch / Tilt
//
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
index d1075454e8..deebfbac63 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
@@ -40,6 +40,7 @@ public class MapboxMap {
private MapView mMapView;
private UiSettings mUiSettings;
private CameraPosition mCameraPosition;
+ private boolean mInvalidCameraPosition;
private String mStyleUrl;
private List<Marker> mSelectedMarkers;
private List<InfoWindow> mInfoWindows;
@@ -60,6 +61,7 @@ public class MapboxMap {
MapboxMap(@NonNull MapView mapView) {
mMapView = mapView;
+ mMapView.addOnMapChangedListener(new MapChangeCameraPositionListener());
mUiSettings = new UiSettings(mapView);
mSelectedMarkers = new ArrayList<>();
mInfoWindows = new ArrayList<>();
@@ -89,6 +91,16 @@ public class MapboxMap {
* @return The current position of the Camera.
*/
public final CameraPosition getCameraPosition() {
+ if (mInvalidCameraPosition) {
+ // Camera position has changed, need to regenerate position
+ mCameraPosition = new CameraPosition.Builder(true)
+ .bearing((float) mMapView.getBearing())
+ .target(mMapView.getLatLng())
+ .tilt((float) mMapView.getTilt())
+ .zoom((float) mMapView.getZoom())
+ .build();
+ mInvalidCameraPosition = false;
+ }
return mCameraPosition;
}
@@ -120,6 +132,17 @@ public class MapboxMap {
* Ease the map according to the update with an animation over a specified duration, and calls an optional callback on completion. See CameraUpdateFactory for a set of updates.
* If getCameraPosition() is called during the animation, it will return the current location of the camera in flight.
*
+ * @param update The change that should be applied to the camera.
+ */
+ @UiThread
+ public final void easeCamera(CameraUpdate update) {
+ easeCamera(update, MapboxConstants.ANIMATION_DURATION);
+ }
+
+ /**
+ * Ease the map according to the update with an animation over a specified duration, and calls an optional callback on completion. See CameraUpdateFactory for a set of updates.
+ * If getCameraPosition() is called during the animation, it will return the current location of the camera in flight.
+ *
* @param update The change that should be applied to the camera.
* @param durationMs The duration of the animation in milliseconds. This must be strictly positive, otherwise an IllegalArgumentException will be thrown.
*/
@@ -1036,7 +1059,7 @@ public class MapboxMap {
mMapView.invalidateCustomLayers();
}
- MapView getMapView(){
+ MapView getMapView() {
return mMapView;
}
@@ -1218,4 +1241,15 @@ public class MapboxMap {
void onFinish();
}
+ private class MapChangeCameraPositionListener implements MapView.OnMapChangedListener {
+ @Override
+ public void onMapChanged(@MapView.MapChange int change) {
+ if (!mInvalidCameraPosition && (change == MapView.REGION_DID_CHANGE
+ || change == MapView.REGION_DID_CHANGE_ANIMATED
+ || change == MapView.REGION_WILL_CHANGE
+ || change == MapView.REGION_WILL_CHANGE_ANIMATED)) {
+ mInvalidCameraPosition = true;
+ }
+ }
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index 26c271784b..c39c462cf7 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -23,7 +23,8 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
- <activity android:name=".MapboxMapActivity"
+ <activity
+ android:name=".MapboxMapActivity"
android:label="@string/action_mapboxmap" />
<activity
android:name=".VisibleCoordinateBoundsActivity"
@@ -80,6 +81,9 @@
<activity
android:name=".DoubleMapActivity"
android:label="@string/activity_double_map" />
+ <activity
+ android:name=".ScrollByActivity"
+ android:label="@string/activity_scroll_by" />
<meta-data
android:name="com.mapbox.AccessToken"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
index 38619d8a00..0ba62a7ce0 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
@@ -452,6 +452,10 @@ public class MainActivity extends AppCompatActivity {
startActivity(new Intent(getApplicationContext(), GeocoderActivity.class));
return true;
+ case R.id.action_scroll_by:
+ startActivity(new Intent(getApplicationContext(), ScrollByActivity.class));
+ return true;
+
default:
return changeMapStyle(menuItem.getItemId());
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ScrollByActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ScrollByActivity.java
new file mode 100644
index 0000000000..47b81d35a8
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ScrollByActivity.java
@@ -0,0 +1,166 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.StringRes;
+import android.support.design.widget.FloatingActionButton;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import com.mapbox.mapboxsdk.constants.Style;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.maps.UiSettings;
+import com.mapbox.mapboxsdk.utils.ApiAccess;
+
+public class ScrollByActivity extends AppCompatActivity {
+
+ public static final int MULTIPLIER_PER_PIXEL = 50;
+
+ private MapView mMapView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_scroll_by);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ final SeekBar xBar = (SeekBar) findViewById(R.id.seekbar_move_x);
+ TextView xText = (TextView) findViewById(R.id.textview_x);
+ xBar.setOnSeekBarChangeListener(new PixelBarChangeListener(xText, R.string.scrollby_x_value));
+
+ final SeekBar yBar = (SeekBar) findViewById(R.id.seekbar_move_y);
+ TextView yText = (TextView) findViewById(R.id.textview_y);
+ yBar.setOnSeekBarChangeListener(new PixelBarChangeListener(yText, R.string.scrollby_y_value));
+
+ mMapView = (MapView) findViewById(R.id.mapView);
+ mMapView.setTag(true);
+ mMapView.setAccessToken(ApiAccess.getToken(this));
+ mMapView.onCreate(savedInstanceState);
+ mMapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull final MapboxMap mapboxMap) {
+ mapboxMap.setStyle(Style.MAPBOX_STREETS);
+
+ UiSettings uiSettings = mapboxMap.getUiSettings();
+ uiSettings.setLogoEnabled(false);
+ uiSettings.setAttributionEnabled(false);
+
+ LatLng grenada = new LatLng(37.176546, -3.599007);
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(grenada, 16));
+
+ FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
+ fab.setColorFilter(ContextCompat.getColor(ScrollByActivity.this, R.color.primary));
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mapboxMap.easeCamera(CameraUpdateFactory.scrollBy(
+ xBar.getProgress() * MULTIPLIER_PER_PIXEL,
+ yBar.getProgress() * MULTIPLIER_PER_PIXEL)
+ );
+ }
+ });
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mMapView.onStart();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mMapView.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mMapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mMapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mMapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mMapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mMapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ private static class PixelBarChangeListener implements SeekBar.OnSeekBarChangeListener {
+
+ @StringRes
+ private int mPrefixTextResource;
+ private TextView mValueView;
+
+ public PixelBarChangeListener(@NonNull TextView textView, @StringRes int textRes) {
+ mValueView = textView;
+ mPrefixTextResource = textRes;
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ int value = progress * ScrollByActivity.MULTIPLIER_PER_PIXEL;
+ mValueView.setText(String.format(seekBar.getResources().getString(mPrefixTextResource), value));
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+
+ }
+ }
+
+
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_input_24dp.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_input_24dp.xml
new file mode 100644
index 0000000000..fea69dfb79
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_input_24dp.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M21,3.01H3c-1.1,0 -2,0.9 -2,2V9h2V4.99h18v14.03H3V15H1v4.01c0,1.1 0.9,1.98 2,1.98h18c1.1,0 2,-0.88 2,-1.98v-14c0,-1.11 -0.9,-2 -2,-2zM11,16l4,-4 -4,-4v3H1v2h10v3z"/>
+</vector>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_scroll_by.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_scroll_by.xml
new file mode 100644
index 0000000000..17e0f35729
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_scroll_by.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/primary"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingBottom="8dp">
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="12dp"
+ android:paddingBottom="8dp"
+ android:textSize="20sp"
+ android:textColor="#FFFFFF"
+ android:text="Move the map by x/y pixels" />
+
+ <TextView
+ android:id="@+id/textview_x"
+ android:layout_alignBottom="@+id/seekbar_move_x"
+ android:layout_below="@id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="X: 0000" />
+
+ <SeekBar
+ android:id="@id/seekbar_move_x"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/title"
+ android:layout_marginLeft="56dp"
+ android:max="50"
+ android:progress="0" />
+
+ <TextView
+ android:id="@+id/textview_y"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBottom="@+id/seekbar_move_y"
+ android:text="Y: 0000" />
+
+ <SeekBar
+ android:id="@id/seekbar_move_y"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/seekbar_move_x"
+ android:layout_marginBottom="8dp"
+ android:layout_marginTop="16dp"
+ android:layout_marginLeft="56dp"
+ android:max="50"
+ android:progress="0" />
+
+ </RelativeLayout>
+
+ </android.support.v7.widget.Toolbar>
+
+ <FrameLayout
+ android:id="@+id/content_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_below="@+id/toolbar">
+
+ <android.support.design.widget.CoordinatorLayout
+ android:id="@+id/coordinator_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.mapbox.mapboxsdk.maps.MapView
+ android:id="@+id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <android.support.design.widget.FloatingActionButton
+ android:id="@+id/fab"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end|bottom"
+ android:layout_margin="@dimen/fab_margin"
+ android:src="@drawable/ic_input_24dp"
+ app:backgroundTint="@color/white" />
+
+ </android.support.design.widget.CoordinatorLayout>
+
+ </FrameLayout>
+
+</RelativeLayout>
+
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
index 67857c9517..b008a4f636 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
@@ -76,7 +76,7 @@
android:id="@+id/action_mapboxmap"
android:checkable="false"
android:icon="@drawable/ic_mapboxmap"
- android:title="@string/action_mapboxmap"/>
+ android:title="@string/action_mapboxmap" />
<item
android:id="@+id/action_tilt"
@@ -84,10 +84,11 @@
android:icon="@drawable/ic_tilt"
android:title="@string/action_tilt" />
- <item android:id="@+id/action_camera"
- android:checkable="false"
- android:icon="@drawable/ic_transform_24dp"
- android:title="@string/action_camera"/>
+ <item
+ android:id="@+id/action_camera"
+ android:checkable="false"
+ android:icon="@drawable/ic_transform_24dp"
+ android:title="@string/action_camera" />
<item
android:id="@+id/action_map_fragment"
@@ -185,6 +186,12 @@
android:icon="@drawable/ic_directions"
android:title="@string/activity_geocoder" />
+ <item
+ android:id="@+id/action_scroll_by"
+ android:checkable="false"
+ android:icon="@drawable/ic_input_24dp"
+ android:title="@string/activity_scroll_by" />
+
</menu>
</item>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
index fd8fed476f..773642f291 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
@@ -24,6 +24,7 @@
<string name="activity_directions">Directions Activity</string>
<string name="activity_geocoder">Geocoder Activity</string>
<string name="activity_double_map">Double Map Activity</string>
+ <string name="activity_scroll_by">Scroll By Activity</string>
<string name="navdrawer_menu_title_mainactivity_controls">Main Activity Controls</string>
<string name="navdrawer_menu_title_mainactivity_styles">Main Activity Styles</string>
@@ -91,4 +92,7 @@
<string name="zoom_botton">Zoom</string>
+ <string name="scrollby_x_value">X: %1$d</string>
+ <string name="scrollby_y_value">Y: %1$d</string>
+
</resources>