2010-12-09 3 views
6

Когда я использую MapController.setZoom (x) и, например, увеличиваю с 5 до 15, масштаб выполняется очень быстро, и часто плитки на новом уровне не загружаются.Плавное масштабирование mapview

Это не очень удобно для пользователя. Любая функция построения карт позволяет изменить это на более медленное масштабирование, чтобы плитки могли загружаться или, по крайней мере, почти загружаться, до достижения уровня 15?

С наилучшими пожеланиями

P

+2

Там является большим преимуществом скорости он оживляется: количество бесполезных загруженных изображений снижается. Когда вы работаете с образцами @ 1ka и @Reuben, это приведет к большому количеству загрузок битмап-приложений (возможно) сети 3G/UMTS, которые будут выброшены через 350 мс позже. Это пустая трата, а иногда и чистая прибыль от пользователя. Также имейте в виду, что даже карта google в pc-браузере работает таким образом, и все к ней привыкли. Никто не ожидает, что карта будет загружена при переключении отображаемого местоположения. – WarrenFaith 2011-06-10 15:37:50

ответ

0

Там нет простой способ сделать это. Однако я могу помочь вам.

Во-первых, вот свободный подарок одного из моих личных полезных классов, 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; 
    } 
} 

То, что я рекомендую вам сделать, это использовать MapController.zoomToSpan() в сочетании с твин ... вот некоторые полностью непроверенный код, который должен работать, возможно, с настройкой или двумя, вы просто передаете ему целевое значение lat & lon spans. :

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

Спасибо, Рубен! Я пробовал это, но на каждом тике (в обратном вызове onTick()) он не обновляет mapview, который я бы использовал, чтобы этот метод выполнял mapView.getController(). ZoomToSpan ((int) latSpan, (int) lonSpan); Пока он выглядит в телефоне, как пауза в течение 5 секунд, а не масштабирование до последнего уровня. Есть идеи? – 2010-12-12 07:26:10

+1

О, черт, я уверен, zoomToSpan начинает свою собственную анимацию ... это очень раздражает. Так жаль. Если бы вы могли сразу установить уровень масштабирования с плавающей точкой, это сработало бы ... его странным, насколько слабые классы Google Maps. – 2010-12-12 09:16:00

8

Более простой способ воспользоваться методом MapController.zoomIn(), что обеспечивает некоторую простую анимацию для увеличения уровня шага.

Вот код:

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

Что она делает это создать последовательность запаздывающих runnables каждый из которых будет вызывать ZoomIn() 350 мс после того, как предыдущий.

Это предполагает, что у вас есть обработчик подключен к основному потоку пользовательского интерфейса под название «обработчиком»

:-)

Смежные вопросы