diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java index a5c6397b6..d4eb390ab 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java @@ -126,6 +126,12 @@ public abstract class BaseMarkerViewOptions 360) { + this.rotation -= 360; + } + while (this.rotation < 0) { + this.rotation += 360; + } return getThis(); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java index b94b24025..b1008e290 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java @@ -1,18 +1,12 @@ package com.mapbox.mapboxsdk.annotations; -import android.animation.AnimatorSet; import android.graphics.Bitmap; -import android.graphics.PointF; import android.support.annotation.FloatRange; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.view.View; -import android.view.animation.AnimationUtils; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.utils.AnimatorUtils; /** * MarkerView is an annotation that shows an View at a geographical location. @@ -231,7 +225,10 @@ public class MarkerView extends Marker { } /** - * Set the rotation value of the MarkerView. + * Set the rotation value of the MarkerView in degrees. + *
+ * Input will be limited to 0 - 360 degrees + *
** This will result in animating the rotation of the MarkerView using an rotation animator * from current value to the provided parameter value. @@ -240,9 +237,26 @@ public class MarkerView extends Marker { * @param rotation the rotation value to animate to */ public void setRotation(float rotation) { - this.rotation = rotation; + // limit to 0 - 360 degrees + float newRotation = rotation; + while (newRotation > 360) { + newRotation -= 360; + } + while (newRotation < 0) { + newRotation += 360; + } + + // calculate new direction + float diff = newRotation - this.rotation; + if (diff > 180.0f) { + diff -= 360.0f; + } else if (diff < -180.0f) { + diff += 360.f; + } + + this.rotation = newRotation; if (markerViewManager != null) { - markerViewManager.animateRotation(this, rotation); + markerViewManager.animateRotationBy(this, diff); } } @@ -339,7 +353,7 @@ public class MarkerView extends Marker { public void setMapboxMap(MapboxMap mapboxMap) { super.setMapboxMap(mapboxMap); - if(isFlat()) { + if (isFlat()) { // initial tilt value if MapboxMap is started with a tilt attribute tiltValue = (float) mapboxMap.getCameraPosition().tilt; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java index 4742c9b66..fe1a48993 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java @@ -15,7 +15,6 @@ import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.maps.Projection; import com.mapbox.mapboxsdk.utils.AnimatorUtils; import java.util.ArrayList; @@ -71,6 +70,19 @@ public class MarkerViewManager { } } + /** + * Animate a MarkerView with a given rotation. + * + * @param marker the MarkerView to rotate by + * @param rotation the rotation by value + */ + public void animateRotationBy(@NonNull MarkerView marker, float rotation) { + View convertView = markerViewMap.get(marker); + if (convertView != null) { + AnimatorUtils.rotateBy(convertView, rotation); + } + } + /** * Animate a MarkerView to a given alpha value. *
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java
index 495393c25..ab3b84104 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java
@@ -7,6 +7,7 @@ import android.animation.ObjectAnimator;
import android.support.annotation.AnimatorRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.view.View;
public class AnimatorUtils {
@@ -61,6 +62,17 @@ public class AnimatorUtils {
rotateAnimator.start();
}
+ public static void rotateBy(@NonNull final View view, float rotationBy) {
+ view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ view.animate().rotationBy(rotationBy).setInterpolator(new FastOutSlowInInterpolator()).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ view.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+ });
+ }
+
public static void alpha(@NonNull final View convertView, float alpha, @Nullable final OnAnimationEndListener listener) {
convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(convertView, View.ALPHA, convertView.getAlpha(), alpha);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java
index ccce72713..8d678794c 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java
@@ -41,16 +41,6 @@ import java.util.Random;
public class MarkerViewActivity extends AppCompatActivity {
- private MapboxMap mapboxMap;
- private MapView mapView;
-
- private MarkerView movingMarkerOne;
- private MarkerView movingMarkerTwo;
- private Random randomAnimator = new Random();
- private Handler locationUpdateHandler = new Handler();
- private Runnable moveMarkerRunnable = new MoveMarkerRunnable();
- private int rotation = 0;
-
private static final LatLng[] LAT_LNGS = new LatLng[]{
new LatLng(38.897424, -77.036508),
new LatLng(38.909698, -77.029642),
@@ -60,6 +50,22 @@ public class MarkerViewActivity extends AppCompatActivity {
new LatLng(38.888000, -77.050000) //Slight overlap to show re-ordering on selection
};
+ private MapboxMap mapboxMap;
+ private MapView mapView;
+
+ // MarkerView location updates
+ private MarkerView movingMarkerOne;
+ private MarkerView movingMarkerTwo;
+ private Random randomAnimator = new Random();
+ private Handler locationUpdateHandler = new Handler();
+ private Runnable moveMarkerRunnable = new MoveMarkerRunnable();
+
+ // MarkerView rotate updates
+ private MarkerView rotateMarker;
+ private Handler rotateUpdateHandler = new Handler();
+ private Runnable rotateMarkerRunnable = new RotateMarkerRunnable();
+ private int rotation = 360;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -111,10 +117,13 @@ public class MarkerViewActivity extends AppCompatActivity {
.position(new LatLng(38.902580, -77.050102))
);
- MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions()
+ rotateMarker = MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions()
.text("A")
+ .rotation(rotation = 270)
.position(new LatLng(38.889876, -77.008849))
);
+ loopMarkerRotate();
+
MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions()
.text("B")
@@ -167,6 +176,10 @@ public class MarkerViewActivity extends AppCompatActivity {
});
}
+ private void loopMarkerRotate() {
+ rotateUpdateHandler.postDelayed(rotateMarkerRunnable, 800);
+ }
+
@Override
protected void onStart() {
super.onStart();
@@ -183,27 +196,49 @@ public class MarkerViewActivity extends AppCompatActivity {
locationUpdateHandler.removeCallbacks(moveMarkerRunnable);
}
+ /**
+ * Updates the position of a Marker
+ */
private class MoveMarkerRunnable implements Runnable {
@Override
public void run() {
int i = randomAnimator.nextInt(9);
if (randomAnimator.nextInt() % 2 == 0) {
movingMarkerOne.setPosition(CarLocation.CAR_0_LNGS[i]);
- movingMarkerOne.setRotation(rotation = rotation + 45);
} else {
movingMarkerTwo.setPosition(CarLocation.CAR_1_LNGS[i]);
- movingMarkerTwo.setRotation(rotation = rotation + 90);
}
loopMarkerMove();
}
}
+ /**
+ * Updates the rotation of a Marker
+ */
+ private class RotateMarkerRunnable implements Runnable {
+
+ private final static int ROTATION_INCREASE_VALUE = 9;
+
+ @Override
+ public void run() {
+ rotation -= ROTATION_INCREASE_VALUE;
+ if (rotation >= 0) {
+ rotation += 360;
+ }
+ rotateMarker.setRotation(rotation);
+ loopMarkerRotate();
+ }
+ }
+
+ /**
+ * Adapts a MarkerView to display an abbreviated name in a TextView and a flag in an ImageView.
+ */
private static class CountryAdapter extends MapboxMap.MarkerViewAdapter