From 27da49c5fb72dd4e3f2c7237c3e4f73fe56c73a2 Mon Sep 17 00:00:00 2001 From: Antonio Zugaldia Date: Thu, 9 Jun 2016 15:15:44 -0400 Subject: [PATCH] first approach to a marker continuosly chasing another --- .../mapboxsdk/annotations/MarkerView.java | 12 ++ .../annotation/AnimatedMarkerActivity.java | 127 ++++++++++++++++-- .../drawable/ic_directions_car_black_24dp.xml | 9 ++ .../drawable/ic_directions_run_black_24dp.xml | 9 ++ 4 files changed, 144 insertions(+), 13 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_directions_car_black_24dp.xml create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_directions_run_black_24dp.xml 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 @@ + + +