0

I override the drawMyLocation of MyLocationOverlay to display an arrow as marker instead of the normal blue dot. However, I also need to change the direction to which the pointer is pointing depending on the sensor of the phone. I decided to call drawMyLocation inside onSensorChanged. But one of the parameters required to call drawMyLocation is a Canvas. How can I access the Canvas of the MyLocationOverlay? Or do I need to create a new Canvas and pass the new Canvas everytime I call drawMyLocation inside onSensorChanged?

Below is my code when I tried to override draw method. However, even though I can see that it was continuously being executed, it takes a while for the rotated bitmap to display.

**UPDATE: If I try to touch my map, I can see my arrow rotating as I touch the map. However, if I don't touch it, it takes a while for the arrow to update its direction.

public boolean draw(android.graphics.Canvas canvas, MapView mapView, boolean shadow, long when) 
{
    Log.v("Message", "Executing draw method...");        
    boolean result;        
    result = super.draw(canvas, mapView, shadow, when);

    if(geoLastFix != null) //geoLastFix contains the GeoPoint of my Location.
    {
        Point screenPts = mapView.getProjection().toPixels(geoLastFix, null);

        //rotate bitmap
        Bitmap arrowBitmap = marker;
        Matrix matrix = new Matrix();           
        matrix.postRotate(orientation);
        Bitmap rotatedBmp = Bitmap.createBitmap(
            arrowBitmap, 
            0, 0, 
            arrowBitmap.getWidth(), 
            arrowBitmap.getHeight(), 
            matrix, 
            true
        );
       //print bitmap to canvas
        canvas.drawBitmap(
            rotatedBmp, 
            screenPts.x - (rotatedBmp.getWidth()  / 2), 
            screenPts.y - (rotatedBmp.getHeight() / 2), 
            null
        );
    }        
    return result;
}
Arci
  • 6,647
  • 20
  • 70
  • 98

1 Answers1

1

You should not be accessing the canvas outside of the draw() method. If you find yourself needing to do drawing or use the canvas, you should override the draw() method.

Use the onSensonrChanged method to save the current orientation or sensor information into your classes state and then override the draw() method and use the saved state to augment your drawing routine.

Nick Campion
  • 10,479
  • 3
  • 44
  • 58
  • However, I'm not sure what the draw method originally does and it might be a pain to code whatever it does if ever. Actually, I tried looking for the Google map API. Only to find out that it was not open-source. Also, overriding the draw method won't guarantee that it will always be called once the sensor changes. Do you know what triggers the draw method? Can you provide the code for the draw method so that I may know what it does originally? – Arci Feb 03 '12 at 07:50
  • the draw method will be called every time the window is updated. This happens on the order of 15-30 times per second and probably 4 to 5 orders of magnitude more often then the sensor will change. When you override the draw method, you call super.draw() as the first step which allows the existing code to do its drawing first, and then you draw on top of that. I, of course, have as little of the code as you do, but I can assure you that drawing to a canvas outside a scope controlled by the draw() method is not the solution. – Nick Campion Feb 03 '12 at 07:55
  • Thanks! I'm also having my doubts on calling the drawMyLocation method on a different method. One thing that I'm still concerned of is that I need to create a new rotated Bitmap everytime the draw method is called. Won't it be too resource intensive as instantiating a new object cause a lot of memory? – Arci Feb 03 '12 at 08:01
  • You load your bitmap once and you can use the translate and rotate methods available on the canvas to apply the bitmap differently to the canvas depending on the current situation. There are a whole bunch of information in the Canvas docs. – Nick Campion Feb 03 '12 at 08:06
  • I just tried overriding the draw method. I'm not sure why but even though I can see that it is continuously being executed, it takes a while to see the arrow rotate. It just suddenly changes its orientation. I've added my code above. For the mean time, I haven't explored rotating the image using the Canvas yet. – Arci Feb 03 '12 at 08:41
  • you can move the entire part labled "rotate bitmap" outside of the draw. That should speed up your code. Also, when you get an orientation change, you should call invalidate to make sure the view is redrawn. – Nick Campion Feb 03 '12 at 15:58