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:


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: , , , , , , , , , ,


Comments:
Jon,
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" />
 
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?
 
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.
 
you are great. Thank you.
 
Hi, can you share source code?
 
Sounds great.
Problem is: It does not work.
pan-events by the user are not detected. :/
 
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
 
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!
 
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
 
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

 
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.
 
High quality blog with lots of information and useful content. 사설토토 놀이터 추천

 
I am glad to see the best textbook. Thanks for sharing useful articles. 토토사이트

 
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.
 
Ms. Rifici has 13 years of experience in traffic tickets, criminal defense, DUI, and white-collar crime, offering free consultations and video conferencing. 
JUSTIA
When selecting a traffic lawyer, consider factors such as experience, areas of specialization, client reviews, and consultation availability to ensure you choose the best representation for your specific situation.stafford traffic lawyer
 

Post a Comment

Subscribe to Post Comments [Atom]





<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]