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?
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); } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With