Cómo animar un marcador a través de un ArrayList de LatLng puntos?

Estoy usando Google Maps API V2 para obtener la ubicación del usuario actual y estoy registrando su ruta usando el oyente onLocationChanged. Mientras el usuario registra su ruta, guardo todos los LatLngs detectados en cada cambio de ubicación en un arraylist. Cuando el usuario deja de registrar su ruta, coloco un marcador en el primer punto del arraylist. Mi problema ahora es que deseo animar el marcador a través de todos los puntos en el arraylist. ¿Puede alguien por favor decirme cómo puedo hacer esto?

Cosas a tener en cuenta es que la matriz no necesita ordenar porque grabo los puntos a medida que vienen. He intentado utilizar un bucle for para recorrer la matriz y enviar los valores, pero me sale un error de la

final LatLng startLatLng = proj.fromScreenLocation (startPoint);

diciendo "Fuente desconocida" junto con una excepción NullPointer.

Aquí está mi código:

case R.id.action_replay: int o; for(o=0; o<oldlocPoints.size(); ++o){ if(--o > 1){lastPos = oldlocPoints.get(--o);} toPos = oldlocPoints.get(++o); animateMarker(markerStart, lastPos, toPos); } return true; 

Y esto es cómo trato de animar a través de los marcadores. La principal dificultad que estoy encontrando es que en run () sólo parece querer valores de tipo final, así que no tengo idea de cómo complacerlo.

  //Animates marker through the locations saved from the recorded route public void animateMarker(final Marker marker, LatLng lastPos, final LatLng toPos) { final long duration = 1600; final Handler handler = new Handler(); this.lastPos = lastPos; this.toPos = toPos; final long start = SystemClock.uptimeMillis(); final int o; Projection proj = map.getProjection(); Point startPoint = proj.toScreenLocation(lastPos); final LatLng startLatLng = proj.fromScreenLocation(startPoint); Log.d(TAG, "" + lastPos + "" + toPos); final Interpolator interpolator = new AccelerateDecelerateInterpolator(); handler.post(new Runnable() { @Override public void run() { long elapsed = SystemClock.uptimeMillis() - start; float t = interpolator.getInterpolation((float) elapsed / duration); double lng = t * toPos.longitude + (1 - t) * startLatLng.longitude; double lat = t * toPos.latitude + (1 - t) * startLatLng.latitude; markerStart.setPosition(new LatLng(lat, lng)); //markerStart.setPosition(interpolator.interpolate(t, target, replayEnd)); if (t < 1.0) { //Post again 16ms later == 60 frames per second handler.postDelayed(this, 32); } else { //Animation ended } } }); } 

¿Puede alguien por favor ayudarme?

ACTUALIZACIÓN Mi intento más cercano es este:

 while (i<oldlocPoints.size()){ final long duration = 32; final Handler handler = new Handler(); final long start = SystemClock.uptimeMillis(); Projection proj = map.getProjection(); final LatLng toPos = oldlocPoints.get(i/3); Point startPoint = proj.toScreenLocation(oldlocPoints.get(i)); final LatLng startLatLng = proj.fromScreenLocation(startPoint); final Interpolator interpolator = new AccelerateDecelerateInterpolator(); handler.post(new Runnable() { @Override public void run() { long elapsed = SystemClock.uptimeMillis() - start; float t = interpolator.getInterpolation((float) elapsed / duration); double lng = t * toPos.longitude + (1 - t) * startLatLng.longitude; double lat = t * toPos.latitude + (1 - t) * startLatLng.latitude; markerStart.setPosition(new LatLng(lat, lng)); //markerStart.setPosition(interpolator.interpolate(t, target, replayEnd)); if (t < 1.0) { //Post again 16ms later == 60 frames per second handler.postDelayed(this, 32); } else { //Animation ended } } }); i++; } 

pruebe este código :: primero la clase MarkerAnimation:

 public class MarkerAnimation { static GoogleMap map; ArrayList<LatLng> _trips = new ArrayList<>() ; Marker _marker; LatLngInterpolator _latLngInterpolator = new LatLngInterpolator.Spherical(); public void animateLine(ArrayList<LatLng> Trips,GoogleMap map,Marker marker,Context current){ _trips.addAll(Trips); _marker = marker; animateMarker(); } public void animateMarker() { TypeEvaluator<LatLng> typeEvaluator = new TypeEvaluator<LatLng>() { @Override public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) { return _latLngInterpolator.interpolate(fraction, startValue, endValue); } }; Property<Marker, LatLng> property = Property.of(Marker.class, LatLng.class, "position"); ObjectAnimator animator = ObjectAnimator.ofObject(_marker, property, typeEvaluator, _trips.get(0)); //ObjectAnimator animator = ObjectAnimator.o(view, "alpha", 0.0f); animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationCancel(Animator animation) { // animDrawable.stop(); } @Override public void onAnimationRepeat(Animator animation) { // animDrawable.stop(); } @Override public void onAnimationStart(Animator animation) { // animDrawable.stop(); } @Override public void onAnimationEnd(Animator animation) { // animDrawable.stop(); if (_trips.size() > 1) { _trips.remove(0); animateMarker(); } } }); animator.setDuration(300); animator.start(); } 

y el _latLngInterpolator que es pre-escrito para usted por los desarrolladores de google:

 public interface LatLngInterpolator { public LatLng interpolate(float fraction, LatLng a, LatLng b); public class Spherical implements LatLngInterpolator { @Override public LatLng interpolate(float fraction, LatLng from, LatLng to) { // http://en.wikipedia.org/wiki/Slerp double fromLat = toRadians(from.latitude); double fromLng = toRadians(from.longitude); double toLat = toRadians(to.latitude); double toLng = toRadians(to.longitude); double cosFromLat = cos(fromLat); double cosToLat = cos(toLat); // Computes Spherical interpolation coefficients. double angle = computeAngleBetween(fromLat, fromLng, toLat, toLng); double sinAngle = sin(angle); if (sinAngle < 1E-6) { return from; } double a = sin((1 - fraction) * angle) / sinAngle; double b = sin(fraction * angle) / sinAngle; // Converts from polar to vector and interpolate. double x = a * cosFromLat * cos(fromLng) + b * cosToLat * cos(toLng); double y = a * cosFromLat * sin(fromLng) + b * cosToLat * sin(toLng); double z = a * sin(fromLat) + b * sin(toLat); // Converts interpolated vector back to polar. double lat = atan2(z, sqrt(x * x + y * y)); double lng = atan2(y, x); return new LatLng(toDegrees(lat), toDegrees(lng)); } private double computeAngleBetween(double fromLat, double fromLng, double toLat, double toLng) { // Haversine's formula double dLat = fromLat - toLat; double dLng = fromLng - toLng; return 2 * asin(sqrt(pow(sin(dLat / 2), 2) + cos(fromLat) * cos(toLat) * pow(sin(dLng / 2), 2))); } } } 

y llámelo en su actividad de mapa como:

  MarkerAnimation.animateLine(TripPoints,map,MovingMarker,context); 
  • Cómo obtener la ubicación GPS de Android
  • Actualizaciones de ubicación que no funcionan en interiores como lo reclaman las API del proveedor de ubicaciones de Fusion
  • Obtener ubicación * gruesa * del proveedor de GPS en Android
  • Determinar la ubicación del usuario en los mapas de osm
  • ¿Cómo acceder al cambio de ubicación en segundo plano para Google Maps android API v2?
  • Emulador de Android se reinicia cuando se envía una ubicación falsa
  • Pasar cadenas entre actividades en android
  • Android Compass señala mi ubicación en lugar de norte
  • La API de ubicación de Google Play Service devuelve una ubicación incorrecta a veces
  • ¿Cómo puede obtener una ubicación en android cuando todos los proveedores de ubicación están inhabilitados?
  • ZipCode desde la ubicación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.