2017-01-16 3 views

Antwort

9

Ich habe eine Lösung gefunden, die einem Marker eine pulsierende Animation hinzufügt. Hier ist der Kartenteil, hier Variable "Karte" bezeichnet Ihre Karte.

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

Sie haben dieses Updates vor Ort anrufen, indem PositionChangedListener hinzufügen. Sie können das leicht in den Google Maps-Dokumenten finden. Danach rufen Sie für jede Aktualisierung die obige Methode auf.

Befestigung des Impulsradius etwas denselben Wert, so dass es weder zu groß, noch zu klein

schreiben diese Methode

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

und ändern Sie diese Zeile

userLocation.getAccuracy() 

zu

getDisplayPulseRadius(userLocation.getAccuracy() 

Und auch

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

zu

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

Wenn Sie einen Effekt wie die Farbe wollen transparent verblasst, wenn es groß wird, können Sie diese einfach in der nächsten Zeile verwenden, wo Sie die setzen Radius innerhalb des Animator

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

seine Arbeits, thanx – sunil

+0

hilf mir. wo deine "userLocation.getAccuracy()" – kemdo

+0

Hallo, ich habe deine Anfrage nicht verstanden. "userLocation" ist ein android.location.Location-Objekt. Sie können hier ein Projekt von mir mit vielen Kartenfunktionen überprüfen. https://github.com/itsdebs/MapEasy und die Datei mit all diesen map bezogenen Implementierungen hier. https://github.com/itsdebs/MapEasy/blob/master/app/src/main/java/com/vagabond/mapeasy/maphandler/MapManagerImpl.java Sehen Sie, wenn dies Ihre Frage beantwortet. – 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

Der Code ist in Kotlin geschrieben, Sie können den Code in Java direkt mit Android Studio konvertieren. Eine weitere Sache ist eine Erweiterung von Debanjans Lösung. – mithil1501

Verwandte Themen