2010-07-26 1 views
1

Я хочу разместить анимированный маркер, показывающий текущее местоположение пользователя в Overlay над MapActivity. Мне нужно включить и выключить анимацию. Я думал, что это может быть достигнуто следующим образом:Проблема с использованием Runnable + Handler.postDelayed для анимации маркеров растровых изображений

/** 
* Class to display current location marker above MapActivity 
*/ 
public class MyLocationOverlay extends Overlay { 

    private Canvas canvas; 
    private final Handler handler = new Handler(); 
    private Runnable runnable; 
    private GeoPoint geoPoint; 
    private int xMarker, yMarker; 
    private int markerNumber = 0; 
    private Bitmap marker, marker0, marker1, marker2, marker3; 

    public MyLocationOverlay(Context context) { 
     Resources r = context.getResources(); 
     marker0 = BitmapFactory.decodeResource(r, R.drawable.marker); 
     marker1 = BitmapFactory.decodeResource(r, R.drawable.marker1); 
     marker2 = BitmapFactory.decodeResource(r, R.drawable.marker2); 
     marker3 = BitmapFactory.decodeResource(r, R.drawable.marker3); 
     marker = marker0; 
    } 

    /** Sets location marker is to be drawn at */ 
    public void setLocation(GeoPoint geoPoint) { 
     this.geoPoint = geoPoint; 
    } 

    /** Sets whether marker is to be animated or static */ 
    public void animateMarker(boolean on) { 
     if (on) { // activate animation 
      if (runnable == null) runnable = new Runnable() { 
       public void run() { 
        switch (markerNumber) { 
        case 0: marker = marker0; break; 
        case 1: marker = marker1; break; 
        case 2: marker = marker2; break; 
        case 3: marker = marker3; break; 
        } 
        markerNumber = ++markerNumber % 3; 
        canvas.drawBitmap(marker, xMarker, yMarker, null); 
        handler.postDelayed(this, 500); 
       } 
      }; 
     } else { // cancel animation, make marker static version 
      handler.removeCallbacks(runnable); 
      runnable = null; 
      marker = marker0; 
     } 
    } 

    @Override 
    public void draw(Canvas canvas, MapView mapView, boolean shadow) { 
     if (shadow == false) { 
      Projection projection = mapView.getProjection(); 

      // convert the location to screen pixels   
      Point point = projection.toPixels(geoPoint, null); 

      // record the canvas and the marker position for the animated marker 
      this.canvas = canvas; 
      xMarker = point.x - marker.getWidth()/2; 
      yMarker = point.y - marker.getHeight()/2; 

      // draw the marker centred at the location 
      canvas.drawBitmap(marker, xMarker, yMarker, null); 
     } 
     super.draw(canvas, mapView, shadow); 
    } 

    @Override 
    public boolean onTap(GeoPoint point, MapView mapView) { return false; } 
} 

Конструктор вызывается из главного MapActivity.onResume() с использованием

locationOverlay = MyLocationOverlay(this) 

И одушевленные/ничья вызывается

GeoPoint point = new GeoPoint(latE6, lonE6); 
    locationOverlay.setLocation(point); 
    locationOverlay.animateMarker(true); 
    mapView.getController().animateTo(point); 

Однако метод run() никогда не вызывается. Что я делаю не так?

ответ

1

Хорошо, чтобы ответить на мой собственный вопрос - ключ лежит в документации для Runnable.run(): «Этот метод вызывается, когда поток запускается, который был создан с классом, который реализует Runnable». Так как я звоню это после того, как нить в работу, мне нужно пнуть его с вызовом Handler.postDelayed()

The animateMarker() метод теперь выглядит следующим образом:

public void animateMarker(boolean on) { 
    if (on) { // activate animation 
     if (runnable == null) runnable = new Runnable() { 
      public void run() { 
       if (canvas!=null) { 
        switch (markerNumber) { 
        case 0: marker = marker0; break; 
        case 1: marker = marker1; break; 
        case 2: marker = marker2; break; 
        case 3: marker = marker3; break; 
        } 
        markerNumber = ++markerNumber % 4; 
        mapView.invalidate(xMarker, yMarker, 
          xMarker+wMarker, yMarker+hMarker); 
       } 
       handler.postDelayed(this, 500); 
      } 
     }; 
     handler.postDelayed(runnable, 500); 
    } else { // cancel animation, make marker static version 
     handler.removeCallbacks(runnable); 
     runnable = null; 
     marker = marker0; 
    } 
} 

Он чувствует себя немного запутано для записи холст, mapView & местоположение от onDraw() метод, но это, пожалуй, единственный способ ...

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

  • Нет связанных вопросов^_^