Zoom events that work in an android Mapview - android

I need to redraw the overlay after the user zooms.
What is the best way to do this?
I've tried everything I can think of (saving a getZoomLevel() state, overriding onUserInteraction()), nothing actually works.
The problem is, that draw() is being called when the user clicks zoom, so the information my draw method gets (About the map's state) is different from the state after the mapview finishes zooming.
Also, draw() isn't being called at the end of the zoom, so only if I pan the map the overlay is actually being drawn properly.

As nobody has answered this in 7 months, I will write what I ended up doing.
I used a Handler to refresh the map manually after 500ms, it worked alright.
Handler handler;
handler.postDelayed(refreshRoute, 500);

Have you tried calling mapview.postInvalidate() after the zoom?

Related

how to detect what triggered an android sdk onCameraChange call

I have an application that tracks current location (using LocationListener), continually updating LatLngBounds to keep the track in view. Every time the boundary change causes the map to be redrawn this makes a call to 'onCameraChange'
I want to temporarily halt this process when the user manually expands the map but to do this I need to be able to differentiate between a call to onCameraChange caused by the new LatLngBounds and a call to onCameraChange caused by the manual expansion of the map.
At the moment the onCameraChangeListener is started during the onCreate process.
How can I do that?
You may use a code similar to this issue comment #21.
Thanks for that, it pointed me in the direction to solve the problem.
As it happens, I only want to capture manual input when the user expands the map and so it was quite easy to check the zoom level whenever onCameraChange is called. If the zoom passed by OnCameraChange is greater than the currently recorded zoom then I can be reasonably sure that the user expanded it as a LatLngBounds change will only reduce the zoom level.

Initiate zoom within an Android WebView from a longpress

I am looking for a way to replicate the native WebView zoom on double-tap but triggered via a long press instead. As, with the double-tab zoom I'd like the zoom to scale centered around the point of touch and then be able to scale back out to the default zoom level programmatically.
I was thinking there might be a way to spoof the double-tap gesture to the WebView within the longpress handler and provide it the coordinates of the long press but I am unable to find a way to do it.
Can this be done?
Found a workable if a bit of a hacky solution to this based upon information found in this post:
Double tap Programmatically on WebView
I replaced the content of:
public void simulateDoubleTap()
{
simulateDoubleTapEvent(0);
simulateDoubleTapEvent(2);
simulateDoubleTapEvent(2);
simulateDoubleTapEvent(1);
simulateDoubleTapEvent(0);
}
With:
public void simulateDoubleTap()
{
simulateDoubleTapEvent(MotionEvent.ACTION_DOWN);
simulateDoubleTapEvent(MotionEvent.ACTION_UP);
simulateDoubleTapEvent(MotionEvent.ACTION_DOWN);
simulateDoubleTapEvent(MotionEvent.ACTION_UP);
}
And then added a call to simulateDoubleTap() from within my longpress handler. This seemed to work - but it was not 100% consistent. May want to play with adding some small delays between the events and see if that smooths it out. Also I noticed that when zooming in, things would work with a single event, but it was taking two triggers of the double-tap to zoom back out. This may be because of the gesture handler I am using, or some other issue, but generally this seems to do what I need.

How to force a call to onDrawFrame() on a GLSurfaceView?

I have a UI that haes a GLSurfaceView that shows a polygon.
The UI haves also two buttons ZoomIn and ZoomOut. When the user press these buttons, the zoomIn() and zoomOut() methods of myGLSurfaceView are called.
The problem is that i want that the method onDrawFrame get's called to get reflected the zoom in & out.
Why i want this? because the buttons have setClickable(true); why? because i need that if the user leaves the finger presing the button, the zoom get's applied continuosly until the user releases the buton.
Now it works but it works bad, i need to refresh the GLsurfaceview forcing onDrawFrame
Call gLSurfaceView.requestRender(). This will (from link):
Request that the renderer render a frame. This method is typically used when the render mode has been set to RENDERMODE_WHEN_DIRTY, so that frames are only rendered on demand. May be called from any thread. Must not be called before a renderer has been set.
solved using threads and press/release events of the finger

workaround for mapview overlays not pinch-zooming correctly

If a user does a "pinch zoom" on the map, my overlays don't properly size until the end. This has been noted in other posts, so i assume it is a known issue.
Problem is, my client finds it totally unacceptable, as I am tasked with making the android app look as good as the iphone version.
Is there any way to correct this, even if it is a horrible hack? For instance, can I subclass the mapview and handle drawing or override some other method?
The common solution is to not draw overlay during zoom animation.
UPDATED:
Sorry, I've confused zoom and move.
The problem with zoom is that you can't rely on zoom level. Instead you need to draw your overlay based on MapView.getProjection().

draw is being constantly called in my android map overlay

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 ?
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.
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
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)!
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.
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.
For me it looks like a strange bug - sometimes the draw method is called continously, sometimes not.
see here.
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.
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.

Categories

Resources