Как анимировать маркер в android-карте api V2?

Я хочу реализовать плавный переход для эмуляции маркера автомобиля, перемещающегося по карте.

Возможно ли анимировать маркер в android-карте api v2?

Попробуйте приведенный ниже код, чтобы анимировать маркер на карте Google V2. Вы должны использовать класс Interpolator для применения анимации на маркере и обрабатывать его в обработчике для анимации, как показано ниже:

  public void animateMarker(final Marker marker, final LatLng toPosition, final boolean hideMarker) { final Handler handler = new Handler(); final long start = SystemClock.uptimeMillis(); Projection proj = mGoogleMapObject.getProjection(); Point startPoint = proj.toScreenLocation(marker.getPosition()); final LatLng startLatLng = proj.fromScreenLocation(startPoint); final long duration = 500; final Interpolator interpolator = new LinearInterpolator(); handler.post(new Runnable() { @Override public void run() { long elapsed = SystemClock.uptimeMillis() - start; float t = interpolator.getInterpolation((float) elapsed / duration); double lng = t * toPosition.longitude + (1 - t) * startLatLng.longitude; double lat = t * toPosition.latitude + (1 - t) * startLatLng.latitude; marker.setPosition(new LatLng(lat, lng)); if (t < 1.0) { // Post again 16ms later. handler.postDelayed(this, 16); } else { if (hideMarker) { marker.setVisible(false); } else { marker.setVisible(true); } } } }); } 

Ни одна из версий не работала для меня, поэтому я внедрил свое собственное решение. Он обеспечивает анимацию местоположения и вращения.

 /** * 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(); } } 

Вычисление вращения для определенной доли анимации. Маркер вращается в направлении, близком к началу вращения:

 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; } 

И, наконец, LatLngInterpolator Google:

 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); } } } 

Просто внедрив версию, попробуйте это

 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(); } 

Класс LatLngInterpolator предварительно написан ребятами 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))); } } } 

Затем создайте экземпляр объекта класса MarkerAnimation и вызовите метод следующим образом:

  MarkerAnimation.animateLine(TripPoints,map,MovingMarker,context); 
Intereting Posts
Как мы можем пометить значок ActionBarDrawerToggle Почему путь, нарисованный на масштабированной GLES20RecordingCanvas и простой холст, имеет разные качества? Как установить максимальную ширину на LinearLayout так, чтобы она не растягивалась в ландшафтном режиме? Могу ли я вставлять Javascript-код в пользовательские вкладки Chrome Как обнаружить устройство – Android-телефон или планшет Android? FbDialog не показывает полный контент на более мелких устройствах Android Layout background alpha Ошибка при создании большого приложения Codename One на этапе Dex Android 4.x RemoteControlClient.setTransportControlFlags () не работает? RecyclerView item layout_weight, размеры не обновляются Как переключить режим полета на Android 4.2 и выше с помощью root? Android программно получает данные для конкретного приложения, например: Использование данных, используемых в «Facebook», Проблема с поддержкой Android V7 CardView Library для работы Какое минимальное расстояние по умолчанию для успешного прокрутки в View Pager? SetInputType в EditTextPreference