3

Я использую google maps v2. У меня есть маркер на карте, этот маркер меняет вращение каждый раз. Я хочу, чтобы анимация вращения моего создателя плавно вращалась. Может кто-нибудь помочь, пожалуйстаАнимация вращения маркера в google map v2

ответ

2
static public void rotateMarker(final Marker marker, final float toRotation, GoogleMap map) { 
    final Handler handler = new Handler(); 
    final long start = SystemClock.uptimeMillis(); 
    final float startRotation = marker.getRotation(); 
    final long duration = 1555; 

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

      float rot = t * toRotation + (1 -t) * startRotation; 

      marker.setRotation(-rot > 180 ? rot/2 : rot); 
      if (t < 1.0) { 
       // Post again 16ms later. 
       handler.postDelayed(this, 16); 
      } 
     } 
    }); 
} 

я сумел это сделать :)

+2

Как вы подсчитали, что должно быть toRotation? –

+1

Это действительно плохо работает при прохождении между левой и правой сторонами северного полушария - например: 350deg -> 10deg - оно не движется по часовой стрелке, а против часовой стрелки или в противоположном 10deg -> 350deg - оно не движется против часовой стрелки, а по часовой стрелке, что неправильно. Это займет более короткий оборот. – user007

+0

Мне не удалось это сделать – Reshma

0

Вы хотели бы использовать MarkerOption rotation method

public MarkerOptions rotation (float rotation) 

Устанавливает вращение маркера в градусах по часовой стрелке вокруг точки привязки маркера. Ось вращения перпендикулярна маркеру . Вращение 0 соответствует позиции по умолчанию маркера . Когда маркер плоский на карте, позиция по умолчанию равна Северный выровненный, а поворот таков, что маркер всегда остается на карте . Когда маркер представляет собой рекламный щит, позиция по умолчанию направлена ​​вверх, и вращение таково, что маркер всегда , обращенный к камере. Значение по умолчанию равно 0.

Возвращает объект, для которого был вызван метод, с новым набором поворота .

5

Это мое осуществление плавного движения маркера с вращением имиджмейкера (когда он установлен в FLAT [важно]). Маркер перемещается в требуемое место плавно, плюс его поворачивают на требуемую степень с правильным направлением. Например, при перемещении от 5 до 355 градусов он движется против часовой стрелки, когда 355deg to 5deg движется по часовой стрелке.

public void animateMarker(final Location location) 
{ 
    if (myMarkerLOC != null) { 
     final LatLngInterpolator latLngInterpolator = new LatLngInterpolator.LinearFixed(); 
     ValueAnimator valueAnimator = new ValueAnimator(); 
     final LatLng startPosition = myMarkerLOC.getPosition(); 
     final float startRotation = myMarkerLOC.getRotation(); 
     final float angle = 180 - Math.abs(Math.abs(startRotation - location.getBearing()) - 180); 
     final float right = WhichWayToTurn(startRotation, location.getBearing()); 
     valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() 
     { 
      @Override 
      public void onAnimationUpdate(ValueAnimator animation) 
      { 
       try { 
        if (myMarkerLOC == null) // oops... destroying map during animation... 
        { 
         return; 
        } 
        float v = animation.getAnimatedFraction(); 
        LatLng newPosition = latLngInterpolator.interpolate(v, startPosition, PositionUtil.toLatLng(location)); 
        float rotation = startRotation + right * v * angle; 
        myMarkerLOC.setRotation((float) rotation); 
        myMarkerLOC.setPosition(newPosition); 
       } catch (Exception ex) { 
        // I don't care atm.. 
       } 
      } 
     }); 
     valueAnimator.setFloatValues(0, 1); 
     valueAnimator.setDuration(300); 
     valueAnimator.start(); 
    } 
} 
private float WhichWayToTurn(float currentDirection, float targetDirection) 
{ 
    float diff = targetDirection - currentDirection; 
    if (Math.abs(diff) == 0) 
    { 
     return 0; 
    } 
    if(diff > 180) 
    { 
     return -1; 
    } 
    else 
    { 
     return 1; 
    } 
} 
public interface LatLngInterpolator 
{ 
    public LatLng interpolate(float fraction, LatLng a, LatLng b); 

    public class Linear implements LatLngInterpolator 
    { 
     @Override 
     public LatLng interpolate(float fraction, LatLng a, LatLng b) 
     { 
      double lat = (b.latitude - a.latitude) * fraction + a.latitude; 
      double lng = (b.longitude - a.longitude) * fraction + a.longitude; 
      return new LatLng(lat, lng); 
     } 
    } 
    public 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); 
     } 
    } 
} 

Отсутствует реализация метода "toLatLong":

public static LatLng toLatLng(final Location location) 
{ 
    return new LatLng(location.getLatitude(), location.getLongitude()); 
} 

Я надеюсь, что помогает.

+0

Что такое PositionUtil? –

+0

Я думаю, что PositionUtil - это настраиваемый класс, который имеет метод преобразования объекта Location в объект LatLng. Пожалуйста, поправьте меня, если я ошибаюсь. Это просто рисует несколько маркеров вместо анимации маркера. Можете ли вы объяснить, почему это происходит? –

+1

@The_Martian: PositionUtil - мой класс утилиты для различных вычислений. В этом случае «PositionUtil.toLatLng "является статическим методом, который преобразует местоположение в LatLong. Так что да, вы правы :) – user007

2
boolean isRotating = false; 
public void rotateMarker(final Marker marker, final float toRotation) { 
    if(!isRotating) { 
     isRotating = true; 
     final Handler handler = new Handler(); 
     final long start = SystemClock.uptimeMillis(); 
     final float startRotation = marker.getRotation(); 
     final long duration = 1000; 
     float deltaRotation = Math.abs(toRotation - startRotation) % 360; 
     final float rotation = (deltaRotation > 180 ? 360 - deltaRotation : deltaRotation) * 
       ((toRotation - startRotation >= 0 && toRotation - startRotation <= 180) || (toRotation - startRotation <= -180 && toRotation - startRotation >= -360) ? 1 : -1); 

     final LinearInterpolator interpolator = new LinearInterpolator(); 
     handler.post(new Runnable() { 
      @Override 
      public void run() { 
       long elapsed = SystemClock.uptimeMillis() - start; 
       float t = interpolator.getInterpolation((float) elapsed/duration); 
       marker.setRotation((startRotation + t * rotation) % 360); 
       if (t < 1.0) { 
        // Post again 16ms later. 
        handler.postDelayed(this, 16); 
       } else { 
        isRotating = false; 
       } 
      } 
     }); 
    } 
} 

Вот как я поворачиваю маркер, я не знаю, что это лучший код или нет. Но я думаю, что это предотвратит неправильное вращение. EDIT: Добавить var isRotating (Спасибо @ Trần Văn Huy)

+0

Я искал этот угол расчета! –

1

С @Bhagaskara Liancer answer.Add var isMarkerRotating с помощью маркера поддержки плавно.

private boolean isMarkerRotating = false; 
public void rotateMarker(final Marker marker, final float toRotation) { 
    if(!isMarkerRotating){ 
     final Handler handler = new Handler(); 
     final long start = SystemClock.uptimeMillis(); 
     final float startRotation = marker.getRotation(); 
     final long duration = 1000; 
     float deltaRotation = Math.abs(toRotation - startRotation) % 360; 
     final float rotation = (deltaRotation > 180 ? 360 - deltaRotation : deltaRotation) * ((toRotation - startRotation >= 0 && toRotation - startRotation <= 180) 
       || (toRotation - startRotation <=-180 && toRotation- startRotation>= -360) ? 1 : -1); 

     final LinearInterpolator interpolator = new LinearInterpolator(); 
     handler.post(new Runnable() { 
      @Override 
      public void run() { 
       isMarkerRotating = true; 
       long elapsed = SystemClock.uptimeMillis() - start; 
       float t = interpolator.getInterpolation((float) elapsed/duration); 
       marker.setRotation((startRotation + t* rotation)%360); 
       if (t < 1.0) { 
        // Post again 16ms later. 
        handler.postDelayed(this, 16); 
       }else { 
        isMarkerRotating = false; 
       } 
      } 
     }); 
    } 

} 
Смежные вопросы