Анимация маркеров на Google Maps v2

Каков наилучший способ анимации маркеров на Картах Google с использованием API v2?

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

Каков наилучший способ сделать это с помощью нового API Карт Google?

Некоторые инженеры Google предоставили приятное демо-видео с некоторым изящным примером кода о том, как оживить маркеры от начальной точки до конечной точки для всех различных версий Android:

Соответствующий код находится здесь:

https://gist.github.com/broady/6314689

И хорошее демо-видео всего этого в действии.

http://youtu.be/WKfZsCKSXVQ

СТАРИННЫЙ ОТПРАВЛЕННЫЙ ОТВЕТ НИЖЕ

В документации упоминается, что значки маркера не могут быть изменены:

Значок

Растровое изображение, отображаемое для маркера. Если значок не отображается, отображается значок по умолчанию. Вы можете указать альтернативную окраску значка по умолчанию, используя defaultMarker (float). Вы не можете изменить значок, как только вы создали маркер.

Документация API Google Maps v2

Вам нужно будет отслеживать определенные маркеры, возможно, используя метод, аналогичный описанному здесь: Связать маркер с объектом , затем выяснить, какой маркер вам нужно обновить. Вызовите .remove() на маркере, затем создайте повернутое изображение в зависимости от «направления», которое вы хотите, создайте новый маркер с этим изображением и добавьте новый маркер к карте.

Вам не нужно «очищать» карту, просто удалите маркер, который вы хотите изменить, создайте новый, а затем добавьте его обратно на карту.

К сожалению, новый API карт еще не очень гибкий. Надеюсь, Google продолжает улучшать его.

Маркер имеет новую функцию, добавленную с версии 7 API v2. Marker.setIcon , поэтому вы можете использовать несколько значков для отображения направления.

Пример использования ответа DiscDev (выше):

 LatLng fromLocation = new LatLng(38.5, -100.4); // Whatever origin coordinates LatLng toLocation = new LatLng(37.7, -107.7); // Whatever destination coordinates Marker marker = mMap.addMarker(new MarkerOptions().position(firstLocation)); MarkerAnimation.animateMarkerToICS(marker, toLocation, new LatLngInterpolator.Spherical()); 

И для тех из вас, кто использует GPS / или любого поставщика услуг, который получает обновления местоположения:

 Marker ourGlobalMarker; // We've got a location from some provider of ours, now we can call: private void updateMarkerPosition(Location newLocation) { LatLng newLatLng = new LatLng(newLocation.getLatitude(), newLocation.getLongitude()); if(ourGlobalMarker == null) { // First time adding marker to map ourGlobalMarker = mMap.addMarker(new MarkerOptions().position(newLatLng)); } else { MarkerAnimation.animateMarkerToICS(ourGlobalMarker, newLatLng, new LatLngInterpolator.Spherical()); } } 

ВАЖНЫЙ:

В пределах 1MarkerAnimation.java Если продолжительность анимации установлена ​​на X, и вы получаете обновления местоположения со скоростью меньше X, будет 1MarkerAnimation.java несколько анимаций, и вы можете увидеть, что анимация маркера немного мерцает (что не очень приятно для пользователя ).

Чтобы этого избежать, метод animationMarkerToICS (например, я использовал animationMarkerToICS ) должен выглядеть примерно так:

полная реализация метода:

 private static Animator animator; // MAKING ANIMATOR GLOBAL INSTEAD OF LOCAL TO THE STATIC FUNCTION ... // Ice Cream Sandwich compatible @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public static void animateMarkerToICS(Marker marker, LatLng finalPosition, final LatLngInterpolator latLngInterpolator) { TypeEvaluator typeEvaluator = new TypeEvaluator() { @Override public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) { return latLngInterpolator.interpolate(fraction, startValue, endValue); } }; Property property = Property.of(Marker.class, LatLng.class, "position"); // ADD THIS TO STOP ANIMATION IF ALREADY ANIMATING TO AN OBSOLETE LOCATION if(animator != null && animator.isRunning()) { animator.cancel(); animator = null; } animator = ObjectAnimator.ofObject(marker, property, typeEvaluator, finalPosition); animator.setDuration((long) ANIMATION_DURATION); animator.start(); } 

Наслаждаться.

  //Your code double bearing = 0.0; bearing = getBearing(new LatLng( currentPosition.latitude ,currentPosition.longitude), new LatLng( nextPosition.latitude, nextPosition.longitude)); bearing -= 90; CameraPosition cameraPosition = new CameraPosition .Builder() .target(new LatLng(nextPosition.latitude, nextPosition.longitude)) .bearing((float) bearing) .zoom(ZOOM_LEVEL).build(); mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 5000, null); animatedMarker(currentPosition,nextPosition,busMarker); //Method for finding bearing between two points private float getBearing(LatLng begin, LatLng end) { double lat = Math.abs(begin.latitude - end.latitude); double lng = Math.abs(begin.longitude - end.longitude); if (begin.latitude < end.latitude && begin.longitude < end.longitude) return (float) (Math.toDegrees(Math.atan(lng / lat))); else if (begin.latitude >= end.latitude && begin.longitude < end.longitude) return (float) ((90 - Math.toDegrees(Math.atan(lng / lat))) + 90); else if (begin.latitude >= end.latitude && begin.longitude >= end.longitude) return (float) (Math.toDegrees(Math.atan(lng / lat)) + 180); else if (begin.latitude < end.latitude && begin.longitude >= end.longitude) return (float) ((90 - Math.toDegrees(Math.atan(lng / lat))) + 270); return -1; } private void animatedMarker(final LatLng startPosition,final LatLng nextPosition,final Marker mMarker) { final Handler handler = new Handler(); final long start = SystemClock.uptimeMillis(); final Interpolator interpolator = new AccelerateDecelerateInterpolator(); final float durationInMs = 3000; final boolean hideMarker = false; handler.post(new Runnable() { long elapsed; float t; float v; @Override public void run() { // Calculate progress using interpolator elapsed = SystemClock.uptimeMillis() - start; t = elapsed / durationInMs; v = interpolator.getInterpolation(t); LatLng currentPosition = new LatLng( startPosition.latitude * (1 - t) + nextPosition.latitude * t, startPosition.longitude * (1 - t) + nextPosition.longitude * t); mMarker.setPosition(currentPosition); // Repeat till progress is complete. if (t < 1) { // Post again 16ms later. handler.postDelayed(this, 16); } else { if (hideMarker) { mMarker.setVisible(false); } else { mMarker.setVisible(true); } } } }); } 
  • Как использовать MapView в android с помощью google map V2?
  • API Карт Google для получения маршрута автобуса
  • Не удалось подключиться к заводскому клиенту - борьба с Google Maps
  • как иметь дело с google-картой внутри скрытого div (обновленное изображение)
  • Встраивание карт Google в приложение для Java-приложений
  • Как показать текущее местоположение на карте Google на Android Marshmallow?
  • Как кэшировать fragmentы карты Google для автономного использования?
  • API Карт Google v2: как сделать маркеры доступными для кликов?
  • Выбор Draw / Rectangle Draw в Картах Google
  • API GoogleMaps v3 Создайте только 1 маркер при щелчке
  • Карты Google и Richfaces 3.3.3 (prototype.js 1.6.0.3) Возможная несовместимость
  • Давайте будем гением компьютера.