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 580c3796d..ba7d58b83 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
@@ -12,6 +12,7 @@ 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.
@@ -55,6 +56,7 @@ public class MarkerView extends Marker {
private long startTime;
private long duration;
private long remainingTime;
+ private AnimatorUtils.OnAnimationEndListener animationEndListener;
/**
* Publicly hidden default constructor
@@ -358,6 +360,12 @@ public class MarkerView extends Marker {
}
public void setPosition(LatLng position, long duration) {
+ setPosition(position, duration, null);
+ }
+
+ public void setPosition(LatLng position, long duration, AnimatorUtils.OnAnimationEndListener animationEndListener) {
+ this.animationEndListener = animationEndListener;
+
if (duration <= 0) {
// update position instantly
super.setPosition(position);
@@ -414,6 +422,10 @@ public class MarkerView extends Marker {
this.startTime = startTime;
}
+ AnimatorUtils.OnAnimationEndListener getAnimationEndListener() {
+ return animationEndListener;
+ }
+
PointF getScreenLocation(@NonNull View convertView) {
return new PointF(convertView.getX() + offsetX, convertView.getY() + offsetY);
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java
index bbd7428ea..8a8a2a558 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java
@@ -1,26 +1,42 @@
package com.mapbox.mapboxsdk.testapp.activity.annotation;
+import android.animation.Animator;
import android.animation.TypeEvaluator;
import android.os.Bundle;
-import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.animation.LinearInterpolator;
-import com.mapbox.mapboxsdk.annotations.MarkerView;
+import com.mapbox.mapboxsdk.annotations.Icon;
+import com.mapbox.mapboxsdk.annotations.IconFactory;
+import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
+import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
+import java.util.Random;
+
public class AnimatedMarkerActivity extends AppCompatActivity {
+ private final static String LOG_TAG = "AnimatedMarkerActivity";
+
private MapView mMapView;
+ private MapboxMap mMapboxMap;
+
+ private LatLng dupontCircle = new LatLng(38.90962, -77.04341);
+
+ private Marker passengerMarker = null;
+ private Marker carMarker = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -39,24 +55,109 @@ public class AnimatedMarkerActivity extends AppCompatActivity {
mMapView = (MapView) findViewById(R.id.mapView);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(new OnMapReadyCallback() {
+
@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
+ mMapboxMap = mapboxMap;
+ setupMap();
- LatLng brussels = new LatLng(50.900446, 4.485251);
- final MarkerView marker = mapboxMap.addMarker(new MarkerViewOptions().position(brussels));
-
- // FIXME workaround because view is not actually added at this time
- final LatLng utrecht = new LatLng(52.086224, 5.122309);
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- marker.setPosition(utrecht, 6500l /*animation duration*/);
- }
- }, 1000);
+ addPassenger();
+ addCar();
+ animateMarker(carMarker, carMarker.getPosition(), passengerMarker.getPosition());
}
});
}
+ private void setupMap() {
+ CameraPosition cameraPosition = new CameraPosition.Builder()
+ .target(dupontCircle)
+ .zoom(15)
+ .build();
+ mMapboxMap.setCameraPosition(cameraPosition);
+ }
+
+ private void addPassenger() {
+ LatLng randomLatLng = getLatLngInBounds();
+
+ if (passengerMarker == null) {
+ Icon icon = IconFactory.getInstance(AnimatedMarkerActivity.this)
+ .fromResource(R.drawable.ic_directions_run_black_24dp);
+ passengerMarker = mMapboxMap.addMarker(new MarkerViewOptions()
+ .position(randomLatLng)
+ .icon(icon));
+ } else {
+ passengerMarker.setPosition(randomLatLng);
+ }
+ }
+
+ private void addCar() {
+ LatLng randomLatLng = getLatLngInBounds();
+
+ if (carMarker == null) {
+ Icon icon = IconFactory.getInstance(AnimatedMarkerActivity.this)
+ .fromResource(R.drawable.ic_directions_car_black_24dp);
+ carMarker = mMapboxMap.addMarker(new MarkerViewOptions()
+ .position(randomLatLng)
+ .icon(icon));
+ } else {
+ carMarker.setPosition(randomLatLng);
+ }
+
+ // Make sure the car marker is selected so that it's always brought to the front (#5285)
+ mMapboxMap.selectMarker(carMarker);
+ }
+
+ private LatLng getLatLngInBounds() {
+ LatLngBounds bounds = mMapboxMap.getProjection().getVisibleRegion().latLngBounds;
+ Random generator = new Random();
+ double randomLat = bounds.getLatSouth() + generator.nextDouble() * (bounds.getLatNorth() - bounds.getLatSouth());
+ double randomLon = bounds.getLonWest() + generator.nextDouble() * (bounds.getLonEast() - bounds.getLonWest());
+ return new LatLng(randomLat, randomLon);
+ }
+
+ private void animateMarker(final Marker marker, LatLng from, LatLng to) {
+ ValueAnimator markerAnimator = ValueAnimator.ofObject(new LatLngEvaluator(), (Object[]) new LatLng[]{from, to});
+ markerAnimator.setDuration(5000);
+ markerAnimator.setInterpolator(new LinearInterpolator());
+
+ markerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ if (marker != null) {
+ marker.setPosition((LatLng) animation.getAnimatedValue());
+ }
+ }
+ });
+
+ markerAnimator.addListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ // Nothing
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ Log.d(LOG_TAG, "Animation ended.");
+
+ addPassenger();
+ animateMarker(carMarker, carMarker.getPosition(), passengerMarker.getPosition());
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ // Nothing
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ // Nothing
+ }
+ });
+
+ // Start
+ markerAnimator.start();
+ }
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_zoom, menu);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_directions_car_black_24dp.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_directions_car_black_24dp.xml
new file mode 100644
index 000000000..6d6337c3a
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_directions_car_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_directions_run_black_24dp.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_directions_run_black_24dp.xml
new file mode 100644
index 000000000..d18f6a17c
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_directions_run_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+