2010-12-09 21 views
6

Wenn ich MapController.setZoom (x) verwende und z. B. von Level 5 bis 15 zoome, funktioniert der Zoom sehr schnell und oft werden die Kartenkacheln der neuen Ebene nicht geladen.Zoom in Kartenansicht glätten

Das sieht für den Benutzer nicht so gut aus. Irgendwelche Maps-Funktionen, um dies zu einem langsameren Zoom zu machen, so dass Kacheln geladen oder zumindest fast geladen werden können, bevor Level 15 erreicht wird?

Mit freundlichen Grüßen

P

+2

Es ist ein großer Vorteil der Geschwindigkeit es animiert genannt haben: Die Menge nutzloser geladener Bilder ist reduziert. Wenn man mit den Beispielen arbeitet, die @ 1ka und @Reuben bereitstellen, würde dies dazu führen, dass viele Bitmap-Ladeanrufe auf einem (möglichen) 3G/UMTS-Netzwerk nur 350 ms später weggeworfen werden. Das ist eine Verschwendung von Bandbreite und manchmal reines Geld vom Benutzer. Auch die Google-Karte im PC-Browser funktioniert so und jeder ist daran gewöhnt. Niemand erwartet, dass beim Wechseln des angezeigten Standorts bereits eine Karte geladen ist. – WarrenFaith

Antwort

0

Es gibt keinen einfachen Weg, dies zu tun. Ich kann Ihnen jedoch helfen.

Erstens, hier ist ein Geschenk von einer meiner persönlichen Utility-Klassen, Tween.java:

import android.os.Handler; 

public class Tween { 

    public static interface TweenCallback { 
     public void onTick(float time, long duration); 
     public void onFinished(); 
    } 

    long start; 
    long duration; 
    Handler handler; 
    TweenCallback callback; 

    public Tween(TweenCallback callback) {  
     handler = new Handler(); 
     this.callback = callback; 
    } 
    public void start(final int duration) { 
     start = android.os.SystemClock.uptimeMillis(); 
     this.duration = duration; 
     tickRunnable.run(); 
    } 
    public void stop() { 
     handler.removeCallbacks(tickRunnable); 
    } 
    Runnable tickRunnable= new Runnable() { 
     public void run() { 
      long now = android.os.SystemClock.uptimeMillis(); 
      float time = now - start; 
      boolean finished = (time >= duration); 
      if (finished) { 
       time = duration; 
      } 
      callback.onTick(time, duration); 
      if (!finished) { 
       handler.post(tickRunnable); 
      } 
      else { 
       callback.onFinished(); 
      } 
     } 
    }; 

    // 
    // Tweening functions. The 4 parameters are : 
    // 
    // t - time, ranges from 0 to d 
    // b - begin, i.e. the initial value for the quantity being changed over time 
    // c - change, the amount b will be changed by at the end 
    // d - duration, of the transition, normally in milliseconds. 
    // 
    // All were adapted from http://jstween.sourceforge.net/Tween.js 
    // 
    public static float strongEaseInOut(float t, float b, float c, float d) { 
     t/=d/2; 
     if (t < 1) return c/2*t*t*t*t*t + b; 
     return c/2*((t-=2)*t*t*t*t + 2) + b; 
    } 
    public static float regularEaseIn(float t, float b, float c, float d) { 
     return c*(t/=d)*t + b; 
    } 
    public static float strongEaseIn(float t, float b, float c, float d) { 
     return c*(t/=d)*t*t*t*t + b; 
    } 
} 

Was ich empfehlen Sie verwenden ist MapController.zoomToSpan() in Verbindung mit einem Tween ... hier einige komplett ungeprüfter Code, der funktionieren sollte, vielleicht mit einem Tweak oder zwei, Sie übergeben es einfach das Ziel lat & lon erstreckt sich. :

public void slowZoom(int latE6spanTarget, int lonE6spanTarget) { 
    final float initialLatE6span = mapView.getLatitudeSpan(); 
    final float initialLonE6span = mapView.getLongitudeSpan(); 
    final float latSpanChange = (float)(latE6spanTarget - initialLatE6span); 
    final float lonSpanChange = (float)(lonE6spanTarget - initialLonE6span); 
    Tween tween = new Tween(new Tween.TweenCallback() { 
     public void onTick(float time, long duration) { 
      float latSpan = Tween.strongEaseIn(time, initialLatE6span, latSpanChange, duration); 
      float lonSpan = Tween.strongEaseIn(time, initialLonE6span, lonSpanChange, duration); 
      mapView.getController().zoomToSpan((int)latSpan, (int)lonSpan); 
     } 
     public void onFinished() { 
     } 
    }); 
    tween.start(5000); 
} 
+0

Danke Reuben! Ich habe es versucht, aber auf jedem Tick (in onTick() Callback) es aktualisiert nicht die Mapview, die ich diese Methode würde tun mapView.getController(). ZoomToSpan ((int) latSpan, (int) lonSpan); Momentan sieht es im Telefon so aus, als würde es für 5 Sekunden pausieren und dann auf die letzte Stufe zoomen. Irgendwelche Ideen? –

+1

Oh Hölle, ich wette zoomToSpan startet seine eigene Animation ... das ist sehr irritierend. So leid. Wenn Sie nur eine Gleitkomma-Zoomstufe sofort einstellen könnten, würde es funktionieren ... es ist seltsam, wie schwach die Google Maps-Klassen sind. –

8

Ein einfacher Weg ist, den Vorteil der MapController.zoomIn() -Methode zu übernehmen, die zum Zoomen einen Schritt Ebene eine einfache Animation bietet.

Hier einige Code:

// a Quick runnable to zoom in 
    int zoomLevel = mapView.getZoomLevel(); 
    int targetZoomLevel = 18; 

    long delay = 0; 
    while (zoomLevel++ < targetZoomLevel) { 
     handler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       mapController.zoomIn(); 
      } 
     }, delay); 

     delay += 350; // Change this to whatever is good on the device 
    } 

Was sie tut, ist eine Folge von verzögerten Runnables jeder von denen schaffen zoomIn() 350ms nach dem vorherigen Anruf.

Dies setzt voraus, dass Sie einen Handler an Ihrem Haupt-UI-Thread ‚Handler‘

:-)

+0

Sie könnten auch eine größere Verzögerung hinzufügen, wenn sie sich Level 18 nähert, um ein Gefühl der Verlangsamung zu geben. –

+0

In Bezug auf Warren Faiths Kommentar zur Bandbreite unterscheidet sich das oben Genannte nicht von dem Benutzer, der die Schaltflächen auf dem Bildschirm manuell ein- und auszoomt. Mit einer Verzögerung von 350 bekomme ich kontinuierlich Zoom, aber kein Rendering des Bildes. Ich denke MapView ist schlau genug zu warten, bis alle Aktivitäten beendet sind, bevor man Kacheln anfordert. Aber IDK sicher. –