Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to animate marker in android map api V2?

I want to implement smooth transition to emulate car marker moving on the map.

Is it possible to animate marker in android map api v2?

like image 683
Alexey Zakharov Avatar asked Dec 14 '12 04:12

Alexey Zakharov


1 Answers

None of versions provided worked for me, so I've implemented my custom solution. It provides both - location and rotation animation.

/**  * Method to animate marker to destination location  * @param destination destination location (must contain bearing attribute, to ensure  *                    marker rotation will work correctly)  * @param marker marker to be animated  */ public static void animateMarker(Location destination, Marker marker) {     if (marker != null) {         LatLng startPosition = marker.getPosition();         LatLng endPosition = new LatLng(destination.getLatitude(), destination.getLongitude());          float startRotation = marker.getRotation();          LatLngInterpolator latLngInterpolator = new LatLngInterpolator.LinearFixed();         ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);         valueAnimator.setDuration(1000); // duration 1 second         valueAnimator.setInterpolator(new LinearInterpolator());         valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {             @Override public void onAnimationUpdate(ValueAnimator animation) {                 try {                     float v = animation.getAnimatedFraction();                     LatLng newPosition = latLngInterpolator.interpolate(v, startPosition, endPosition);                     marker.setPosition(newPosition);                     marker.setRotation(computeRotation(v, startRotation, destination.getBearing()));                 } catch (Exception ex) {                     // I don't care atm..                 }             }         });          valueAnimator.start();     } } 

Rotation computation for specified fraction of animation. Marker is rotated in direction which is closer from start to end rotation:

private static float computeRotation(float fraction, float start, float end) {     float normalizeEnd = end - start; // rotate start to 0     float normalizedEndAbs = (normalizeEnd + 360) % 360;      float direction = (normalizedEndAbs > 180) ? -1 : 1; // -1 = anticlockwise, 1 = clockwise     float rotation;     if (direction > 0) {         rotation = normalizedEndAbs;     } else {         rotation = normalizedEndAbs - 360;     }      float result = fraction * rotation + start;     return (result + 360) % 360; }  

And finally Google's LatLngInterpolator:

private interface LatLngInterpolator {     LatLng interpolate(float fraction, LatLng a, LatLng b);      class LinearFixed implements LatLngInterpolator {         @Override         public LatLng interpolate(float fraction, LatLng a, LatLng b) {             double lat = (b.latitude - a.latitude) * fraction + a.latitude;             double lngDelta = b.longitude - a.longitude;             // Take the shortest path across the 180th meridian.             if (Math.abs(lngDelta) > 180) {                 lngDelta -= Math.signum(lngDelta) * 360;             }             double lng = lngDelta * fraction + a.longitude;             return new LatLng(lat, lng);         }     } } 
like image 139
skywall Avatar answered Oct 04 '22 11:10

skywall