2015-03-26 4 views
5

मेरे आवेदन में एक बिंदु से दूसरे बिंदु पर एक चिकनी "चाल" Google मानचित्र मार्कर प्रदर्शित करने की आवश्यकता है।Google नक्शे v2 में मार्कर को सुचारु रूप से स्थानांतरित करने के लिए कैसे सही करें?

public void animateMarker(final Marker marker, final LatLng toPosition, 
          final boolean hideMarker) { 
    final Handler handler = new Handler(); 
    final long start = SystemClock.uptimeMillis(); 
    Projection proj = mMap.getProjection(); 
    Point startPoint = proj.toScreenLocation(marker.getPosition()); 
    final LatLng startLatLng = proj.fromScreenLocation(startPoint); 
    final long duration = 500; 

    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); 
      double lng = t * toPosition.longitude + (1 - t) 
        * startLatLng.longitude; 
      double lat = t * toPosition.latitude + (1 - t) 
        * startLatLng.latitude; 
      marker.setPosition(new LatLng(lat, lng)); 

      if (t < 1.0) { 
       // Post again 16ms later. 
       handler.postDelayed(this, 16); 
      } else { 
       if (hideMarker) { 
        marker.setVisible(false); 
       } else { 
        marker.setVisible(true); 
       } 
      } 
     } 
    }); 
} 

लेकिन बस नए स्थान पर एक नया मार्कर बनाने का एक परिणाम के रूप में (हालांकि वर्ष नहीं हटाया जाता है): मैं निम्न विधि एनीमेशन के लिए उपयोग

enter image description here

+0

मुझे लगता है कि आपको एक स्थिति बदलने के बाद, और प्रतीक्षा करने से पहले दृश्य को फिर से लिखने की आवश्यकता है। – kaho

+0

क्या आपका मतलब एक डिलीट मार्कर था और नई स्थिति के साथ नया जोड़ना था? – Rexhaif

+0

जहां तक ​​मेरी समझ है, संसाधनों को सहेजने के लिए, एंड्रॉइड स्क्रीन को तब तक नहीं खींचता जब तक कि आपका लूप खत्म न हो ... इसलिए आपको उस सिस्टम को बताना होगा कि आप स्क्रीन को फिर से लेना चाहते हैं। ऐसा लगता है कि इससे मदद मिलेगी: http://developer.android.com/reference/android/view/View.html#invalidate(android.graphics.Rect) – kaho

उत्तर

18

मैं कॉपी किया project से कुछ कोड official video में उल्लिखित हैं।

मैंने इसे इस कोड और seems to be working for me के साथ पुन: पेश करने का प्रयास किया, इसलिए उम्मीद है कि मेरा कोड आपकी मदद करेगा, यहां तक ​​कि थोड़ा सा भी।

static final LatLng SomePos = new LatLng(37.7796354, -122.4159606); 

    try { 
     if (googleMap == null) { 
      googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap(); 
     } 
     googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 
     googleMap.setMyLocationEnabled(true); 
     googleMap.setTrafficEnabled(false); 
     googleMap.setIndoorEnabled(false); 
     googleMap.setBuildingsEnabled(true); 
     googleMap.getUiSettings().setZoomControlsEnabled(true); 
     googleMap.moveCamera(CameraUpdateFactory.newLatLng(SomePos)); 
     googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder() 
       .target(googleMap.getCameraPosition().target) 
       .zoom(17) 
       .bearing(30) 
       .tilt(45) 
       .build())); 

     myMarker = googleMap.addMarker(new MarkerOptions() 
       .position(SomePos) 
       .icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher)) 
       .title("Hello world")); 


     googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() 
     { 
      @Override 
      public boolean onMarkerClick(Marker arg0) { 

       final LatLng startPosition = myMarker.getPosition(); 
       final LatLng finalPosition = new LatLng(37.7801569,-122.4148528); 
       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)+finalPosition.latitude*t, 
           startPosition.longitude*(1-t)+finalPosition.longitude*t); 

         myMarker.setPosition(currentPosition); 

         // Repeat till progress is complete. 
         if (t < 1) { 
          // Post again 16ms later. 
          handler.postDelayed(this, 16); 
         } else { 
          if (hideMarker) { 
           myMarker.setVisible(false); 
          } else { 
           myMarker.setVisible(true); 
          } 
         } 
        } 
       }); 

       return true; 

      } 

     }); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
+0

आपको बहुत बहुत धन्यवाद – Rexhaif

3

मैं जानता हूँ कि यह एक पुराने सवाल लेकिन है ...

आप इस कार्य के लिए मूल्य क्षेपक उपयोग कर सकते हैं:

fun changePositionSmoothly(marker:Marker?, newLatLng: LatLng){ 
    if(marker == null){ 
     return; 
    } 
    val animation = ValueAnimator.ofFloat(0f, 100f) 
    var previousStep = 0f 
    val deltaLatitude = newLatLng.latitude - marker.position.latitude 
    val deltaLongitude = newLatLng.longitude - marker.position.longitude 
    animation.setDuration(1500) 
    animation.addUpdateListener { updatedAnimation -> 
     val deltaStep = updatedAnimation.getAnimatedValue() as Float - previousStep 
     previousStep = updatedAnimation.getAnimatedValue() as Float 
     marker.position = LatLng(marker.position.latitude + deltaLatitude * deltaStep * 1/100, marker.position.longitude + deltaStep * deltaLongitude * 1/100) 
    } 
    animation.start() 
} 

त्रुटि संचय रोकने के लिए, एनीमेशन के अंत में आप नई स्थिति निर्धारित कर सकते हैं, लेकिन यह ज्यादातर मामलों के लिए पर्याप्त है।

संबंधित मुद्दे