Monday, March 1, 2010
Responding to zooms and pans in Android's MapView
There's a curious lacuna in Android's MapView API: it's (relatively) easy to display a map, and overlay items atop a map; it's (relatively) easy to detect when an overlay item has been touched; but there's no straightforward way to work out when the user has touched anywhere else on the map. Because of the way MapView works, the usual onTouchListener() solution only works for one touch, and then fails.
There is, however, a solution. Not a pretty one, but it works. The solution is to use your own subclass of MapView:
and within that subclass, override onTouchEvent. You're probably only interested in the UP action:
But what if you want to detect zoom actions as well as touches? Simple, thought I: just override onDraw() and do the same thing. But you can't - MapView's onDraw() is final!
Catastrophe? Not quite. It turns out that overriding dispatchDraw() works just fine:
Et voila - you can programmatically detect and respond when the user pans and/or zooms your map. Really not so hard after all.
There is, however, a solution. Not a pretty one, but it works. The solution is to use your own subclass of MapView:
public class ITRMapView extends MapView {
public ITRMapView(android.content.Context context, android.util.AttributeSet attrs) {
super(context, attrs);
}
public ITRMapView(android.content.Context context, android.util.AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ITRMapView(android.content.Context context, java.lang.String apiKey) {
super(context, apiKey);
}
}
and within that subclass, override onTouchEvent. You're probably only interested in the UP action:
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction()==MotionEvent.ACTION_UP) {
//do your thing
}
return super.onTouchEvent(ev);
}
But what if you want to detect zoom actions as well as touches? Simple, thought I: just override onDraw() and do the same thing. But you can't - MapView's onDraw() is final!
Catastrophe? Not quite. It turns out that overriding dispatchDraw() works just fine:
int oldZoomLevel=-1;
public void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (getZoomLevel() != oldZoomLevel) {
//do your thing
oldZoomLevel = getZoomLevel();
}
}
Et voila - you can programmatically detect and respond when the user pans and/or zooms your map. Really not so hard after all.
Labels: Android, dispatchDraw, MapView, MotionEvent, onDraw, onTouchEvent, onTouchListener, pan, touch, touches, zoom
Comments:
I have read your post and i am here to thank you for sharing this post
Anuncontested divorce lawyer virginia in Virginia specializes in helping couples navigate the legal process of ending their marriage when both parties are in agreement on all key issues.
<< Home
Jon,
Do I need something in the Manifest?
This breaks when I run with my MapView subclass.
mapView = (MyMapViewSubclass)findViewById(R.id.mapview);
Do I need something in the Manifest?
This breaks when I run with my MapView subclass.
mapView = (MyMapViewSubclass)findViewById(R.id.mapview);
Yes - you need a layout entry like
<my.packet.name.MyMapView
android:id="@+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:apiKey="MyGoogleMapsAPIKey"
android:clickable="true" />
<my.packet.name.MyMapView
android:id="@+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:apiKey="MyGoogleMapsAPIKey"
android:clickable="true" />
Sorry, yes I have that...
My map view worked fine until I tried to cast it to my subclass.
Not sure why it's not happy?
Is overriding onUserInteraction() equivalent to overriding dispatchDraw?
My map view worked fine until I tried to cast it to my subclass.
Not sure why it's not happy?
Is overriding onUserInteraction() equivalent to overriding dispatchDraw?
Thank you SO much for posting this. I had a sinking feeling that I'd have to extend the MapView object but tried to find a easier solution. Now if I can just get the ProgressDialog to appear while I'm pulling results from the network I'll be all set! Thanks again.
Nice approach. But have you tried the OnOverlayGestureListener? Wouldn't it be a bit easier?
http://code.google.com/p/mapview-overlay-manager/wiki/OnOverlayGestureListener
http://code.google.com/p/mapview-overlay-manager/wiki/OnOverlayGestureListener
Wouldn't overriding onSizeChanged() be better to override than dispatchDraw()? One would assume that the name "onSizeChanged()" implies it is related to zooming after all.
Hi Jon,
I am following your code for listening to the zooming action. But it cannot even load, always with the "force close" message from the beginning.
I have the following code in my MapActivity class file "public class Ngb2Map extends MapActivity":
private ITRMapView mapView;
mapView = (ITRMapView)findViewById(R.id.mapview);
and "<nottingham.ngb2.ITRMapView ..." instead of "<com.google.android.maps.MapView" in the main.xml file.
I think the error comes from "(ITRMapView)findViewById(R.id.mapview);", but do not know what it should be.
How should I initialize the subclass ITRMapView?
Thanks a lot!
I am following your code for listening to the zooming action. But it cannot even load, always with the "force close" message from the beginning.
I have the following code in my MapActivity class file "public class Ngb2Map extends MapActivity":
private ITRMapView mapView;
mapView = (ITRMapView)findViewById(R.id.mapview);
and "<nottingham.ngb2.ITRMapView ..." instead of "<com.google.android.maps.MapView" in the main.xml file.
I think the error comes from "(ITRMapView)findViewById(R.id.mapview);", but do not know what it should be.
How should I initialize the subclass ITRMapView?
Thanks a lot!
Thanks for sharing this informative content.,
Leanpitch provides online training in Agile team facilitation during this lockdown period everyone can use it wisely.
Team facilitator in Agile
ICAGILE ATF
Leanpitch provides online training in Agile team facilitation during this lockdown period everyone can use it wisely.
Team facilitator in Agile
ICAGILE ATF
Thanks for sharing this informative content.,
Leanpitch provides online training in Agile team facilitation during this lockdown period everyone can use it wisely.
Agile team facilitation
ICP ATF
Team facilitator Agile
Agile facilitator
Team facilitator in Agile
ICAGILE ATF
Leanpitch provides online training in Agile team facilitation during this lockdown period everyone can use it wisely.
Agile team facilitation
ICP ATF
Team facilitator Agile
Agile facilitator
Team facilitator in Agile
ICAGILE ATF
Nice to see you! Writers from essay writing company hold high qualifications in various subject disciplines, making them competent to work on numerous projects. With a thorough hiring process, our recruiters filter the mediocre from the professional writers and retain the top-tier experts.
Even our custom shopify theme development services are facilitated to keep you posted with every change that is being made to the website. We are committed to provide you all sort of digital services by making sure they meet ethical and tech standards
I have read your post and i am here to thank you for sharing this post
Anuncontested divorce lawyer virginia in Virginia specializes in helping couples navigate the legal process of ending their marriage when both parties are in agreement on all key issues.
Subscribe to Post Comments [Atom]
<< Home
Subscribe to Posts [Atom]
Post a Comment