2017-01-16 47 views

Odpowiedz

9

Znalazłem rozwiązanie, aby dodać pulsującą animację do znacznika. Oto część mapy, Tutaj zmienna "mapa" oznacza twoją 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; 
    } 

Musisz zadzwonić po aktualizacji lokalizacji, dodając PositionChangedListener. Możesz łatwo znaleźć to w dokumentach map Google. Następnie dla każdej aktualizacji wywołaj powyższą metodę.

Mocowanie promień impulsu do nieco samą wartość, tak że nie jest to ani za duży, ani za mały

Zapis ten sposób

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

I zmienić ten wiersz

userLocation.getAccuracy() 

to

getDisplayPulseRadius(userLocation.getAccuracy() 

A także

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

do

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

Jeśli chcesz efekt jak kolor blaknie na przezroczyste, gdy robi się duża, można użyć tego właśnie w następnym wierszu, w którym są Ustawianie promień wewnątrz animatora

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

jego pracy, thanx – sunil

+0

pomóż mi. gdzie twój "userLocation.getAccuracy()" – kemdo

+0

Witam, nie zrozumiałem twojego zapytania. "userLocation" to obiekt android.location.Location. Możesz sprawdzić mój projekt z wieloma funkcjami mapy tutaj. https://github.com/itsdebs/MapEasy i plik zawierający wszystkie związane z mapami implementacje tutaj. https://github.com/itsdebs/MapEasy/blob/master/app/src/main/java/com/vagabond/mapeasy/maphandler/MapManagerImpl.java Zobacz, jeśli to odpowiada Twojemu zapytaniu. – 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

Kod jest napisany w Kotlin, możesz bezpośrednio przekonwertować kod w java za pomocą Android Studio. I jeszcze jedno, to rozszerzenie powyższego rozwiązania Debanjana. – mithil1501