2017-01-16 6 views

ответ

9

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

private Circle lastUserCircle; 
private long pulseDuration = 1000; 
private ValueAnimator lastPulseAnimator; 

private void addPulsatingEffect(Latlng userLatlng){ 
      if(lastPulseAnimator != null){ 
       lastPulseAnimator.cancel(); 
       Log.d("onLocationUpdated: ","cancelled"); 
      } 
      if(lastUserCircle != null) 
       lastUserCircle.setCenter(userLatlng); 
      lastPulseAnimator = valueAnimate(userLocation.getAccuracy(), pulseDuration, new ValueAnimator.AnimatorUpdateListener() { 
       @Override 
       public void onAnimationUpdate(ValueAnimator animation) { 
        if(lastUserCircle != null) 
         lastUserCircle.setRadius((Float) animation.getAnimatedValue()); 
        else { 
         lastUserCircle = map.addCircle(new CircleOptions() 
           .center(userLatlng) 
           .radius((Float) animation.getAnimatedValue()) 
           .strokeColor(Color.RED) 
           .fillColor(Color.BLUE)); 
        } 
       } 
      }); 

} 
protected ValueAnimator valueAnimate(float accuracy,long duration, ValueAnimator.AnimatorUpdateListener updateListener){ 
     Log.d("valueAnimate: ", "called"); 
     ValueAnimator va = ValueAnimator.ofFloat(0,accuracy); 
     va.setDuration(duration); 
     va.addUpdateListener(updateListener); 
     va.setRepeatCount(ValueAnimator.INFINITE); 
     va.setRepeatMode(ValueAnimator.RESTART); 

     va.start(); 
     return va; 
    } 

Вы должны называть это на основании обновлений местоположения, добавив PositionChangedListener. Вы можете легко найти это в Google maps docs. После этого для каждого обновления вызывается описанный выше метод.

Закрепление радиус импульса до некоторой степени то же самое значение, так что это не ни слишком большой, ни слишком маленький

Написать этот метод

protected float getDisplayPulseRadius(float radius) { 
     float diff = (map.getMaxZoomLevel() - map.getCameraPosition().zoom); 
     if (diff < 3) 
      return radius; 
     if (diff < 3.7) 
      return radius * (diff/2); 
     if (diff < 4.5) 
      return (radius * diff); 
     if (diff < 5.5) 
      return (radius * diff) * 1.5f; 
     if (diff < 7) 
      return (radius * diff) * 2f; 
     if (diff < 7.8) 
      return (radius * diff) * 3.5f; 
     if (diff < 8.5) 
      return (float) (radius * diff) * 5; 
     if (diff < 10) 
      return (radius * diff) * 10f; 
     if (diff < 12) 
      return (radius * diff) * 18f; 
     if (diff < 13) 
      return (radius * diff) * 28f; 
     if (diff < 16) 
      return (radius * diff) * 40f; 
     if (diff < 18) 
      return (radius * diff) * 60; 
     return (radius * diff) * 80; 
    } 

И изменить эту строку

userLocation.getAccuracy() 

до

getDisplayPulseRadius(userLocation.getAccuracy() 

А также

.radius((Float) animation.getAnimatedValue()) 

в

.radius(getDisplayPulseRadius((Float) animation.getAnimatedValue())) 

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

circle.setFillColor(adjustAlpha(pulseAroundMeFillColor, 1 - animation.getAnimatedFraction())); 

private int adjustAlpha(int color, float factor) { 
     int alpha = Math.round(Color.alpha(color) * factor); 
     int red = Color.red(color); 
     int green = Color.green(color); 
     int blue = Color.blue(color); 
     return Color.argb(alpha, red, green, blue); 
    } 
+0

его работы, спасибо – sunil

+0

помогите мне. где ваш "userLocation.getAccuracy()" – kemdo

+0

Привет, я не понял ваш запрос. «userLocation» - объект android.location.Location. Здесь вы можете проверить мой проект со многими функциями карты. https://github.com/itsdebs/MapEasy и файл со всеми этими реализациями, связанными с картой. https://github.com/itsdebs/MapEasy/blob/master/app/src/main/java/com/vagabond/mapeasy/maphandler/MapManagerImpl.java См., если это ответит на ваш запрос. – Debanjan

1
import android.animation.ValueAnimator 
import android.graphics.Color 
import android.os.Bundle 
import android.support.v7.app.AppCompatActivity 
import com.google.android.gms.maps.CameraUpdateFactory 
import com.google.android.gms.maps.GoogleMap 
import com.google.android.gms.maps.MapFragment 
import com.google.android.gms.maps.model.Circle 
import com.google.android.gms.maps.model.CircleOptions 
import com.google.android.gms.maps.model.LatLng 
import com.google.android.gms.maps.model.MarkerOptions 

class MainActivity : AppCompatActivity() { 

    private val pulseCount = 4 

    private val animationDuration = (pulseCount + 1) * 1000 

    private val SAN_FRANCISCO_LOCATION = LatLng(37.7749295, -122.4194155) 

    private var gMap: GoogleMap? = null 

    private var circles = Array<Circle?>(pulseCount, { null }) 

    override fun onCreate(savedInstanceState: Bundle?) { 
      super.onCreate(savedInstanceState) 
      setContentView(R.layout.activity_main) 

      (fragmentManager.findFragmentById(R.id.mpFrgmnt) as MapFragment).getMapAsync { map -> 
       gMap = map 
       setCurrentLocation() 
      } 
    } 

    private fun setCurrentLocation() { 
      gMap?.let { gMap -> 
    gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SAN_FRANCISCO_LOCATION, 17f)) 
     gMap.animateCamera(CameraUpdateFactory.zoomIn()) 
     gMap.animateCamera(CameraUpdateFactory.zoomTo(17f), animationDuration, null) 
     gMap.addMarker(MarkerOptions().position(SAN_FRANCISCO_LOCATION).title("San Francisco !")) 

      val from = 0 
      val to = 100 
      val fraction = 255/to 

      for (i in 0 until pulseCount) { 
        addPulseAnimator(gMap, circles, SAN_FRANCISCO_LOCATION, from, to, fraction, i) 
      } 
     } 
    } 

    private fun addPulseAnimator(gMap: GoogleMap, circles: Array<Circle?>, latLng: LatLng, from: Int, to: Int, colorFraction: Int, currentPosition: Int) { 
      val valueAnimator = ValueAnimator.ofInt(from, to) 
      valueAnimator.duration = animationDuration.toLong() 
      valueAnimator.repeatCount = ValueAnimator.INFINITE 
      valueAnimator.repeatMode = ValueAnimator.RESTART 
      valueAnimator.startDelay = currentPosition * 1000L 
      valueAnimator.addUpdateListener { valueAnimator -> 

     val radius = valueAnimator.animatedValue as Int 

     circles[currentPosition]?.let { circle -> 
      circle.center = latLng 
      circle.radius = radius.toDouble() 
      circle.fillColor = Color.argb((to - radius) * colorFraction, 48, 118, 254) 
      circle.strokeWidth = 0f 

     } ?: run { 
      circles[currentPosition] = gMap.addCircle(CircleOptions() 
        .center(latLng) 
        .radius(radius.toDouble()) 
        .fillColor(Color.argb((to - radius) * colorFraction, 48, 118, 254)) 
        .strokeWidth(0f)) 
        } 
      } 
      valueAnimator.start() 
     } 
} 
+0

Код написан в Котлине, вы можете напрямую конвертировать код в java с помощью Android Studio. Еще одна вещь - это расширение решения Debanjan выше. – mithil1501