draw is being constantly called in my android map

2019-02-12 09:43发布

问题:

I'm trying to draw a route onto my MapView. I've extended Overlay and implemented the draw() method. The route is displayed properly, although while debugging, I added a breakpoint on draw(), and noticed it is being called constantly.

I only want it to be re-drawn if someone moves the map or zooms (the draw take into account these changes when drawing the route) What can cause this ?

回答1:

There are two draw methods that can be overridden.

void draw(android.graphics.Canvas canvas, MapView mapView, boolean shadow)

Desc: Draw the overlay over the map.

boolean draw(android.graphics.Canvas canvas, MapView mapView, boolean shadow, long when)
Desc: Draw call for animated overlays.

I originally overrided the second one.
After changing to the first method, it worked out.



回答2:

i think the draw method is called repeatedly because the of the background being redrawn constantly. try setting the "MapView.ReticleDrawMode" to DRAW_RETICLE_UNDER. This basically tells the mapView to draw the reticle under the overlays. So overlay's draw method will not be called when the background is recalled. this fixed the issue for me.

for more info, look here: MapView Api



回答3:

I got tripped up when I didn't realize that the draw method get's called not only any markers that you draw, BUT also the shadow of those markers. So as an example, if you have two markers and you have shadows set to true (which is the default setting), then you'll have the draw method being called 4 times (once for each marker, once for each shadow of the markers)!



回答4:

After further review, the Overlay draw() does actually work as described in the documentation. One draw for shadow = true, and one for shadow = false.

The interesting thing is that the specific overlay draw() method responds as advertized for each element drawn in the MapView. For example, in my case, it seems to respond for each the google map, the Google logo drawn on the map, and then the particular overlay I have drawn myself. Obviously twice for each (shadow true|false).

This is probably the intended way to render the maps. I haven't found or spent enough time researching for this information.

Also, in my own case, I have a transparent panel rendered over my map with CheckBox(s) and TextView widgets. The TextView forces the draw() method to run non-stop since the textview is always listening for input and hence triggering the redrawn of the overlay.



回答5:

In my app, I have an indefinite progress bar (e.g. spinning circle) show when I'm loading network data for the map. When the network data is finished loading, I was setting the progress bar's visibility to invisible. However, this caused the map to continuously redraw as it seems that any animation (I'm guessing) which takes place over the map will cause the map itself to redraw. Simple solution to this is to set the visibility to gone instead. E.g. change this:

ProgressBar loadingIcon = (ProgressBar) findViewById(R.id.loadingIcon);
...
//Network data now finished loading...
loadingIcon.setVisibility(View.INVISIBLE);

to this:

loadingIcon.setVisibility(View.GONE);

which removes it entirely from the map, no longer animates over it and therefore does not cause draw() to be called a indefinitely.



回答6:

For me it looks like a strange bug - sometimes the draw method is called continously, sometimes not.

see here.



回答7:

I know this is an old problem, but I just now encountered it. This is a "for what it's worth" post.

The draw loop turned out to be a coding error on my part. According to the doc, if the draw routine returns true, it is asking for an immediate update. If false is returned, only two passes are made for each overlay; one for shadow true and one for shadow false. I was returning true which resulted in a constant update. After I changed to returning false, only two passes per overlay occurred. No loop.



回答8:

You can simply add this to your ItemizedOverlay class:

@Override public void draw( Canvas c, MapView m, boolean shadow ) { super.draw( c, m, false );}

This will remove the shadow from your mapview overlay.