This example demonstrates map click and long-click event handling in OpenMapView, showing how to detect user taps on the map and convert screen coordinates to geographic coordinates.
- Map click listener (single tap)
- Map long-click listener (tap and hold)
- Screen coordinate to LatLng conversion
- Real-time coordinate display via Toast messages
- Lifecycle-safe event handling
- Open the OpenMapView project in Android Studio
- Select
examples.Example06Clicksfrom the run configuration dropdown - Click Run (green play button)
- Deploy to device or emulator
# From project root - build, install, and launch
./gradlew :examples:Example06Clicks:installDebug
# Launch the app
adb shell am start -n de.afarber.openmapview.example06clicks/.MainActivity// Single tap listener
mapView.setOnMapClickListener { latLng ->
Toast.makeText(
this,
"Clicked: ${latLng.latitude}, ${latLng.longitude}",
Toast.LENGTH_SHORT
).show()
}
// Long-press listener
mapView.setOnMapLongClickListener { latLng ->
Toast.makeText(
this,
"Long-clicked: ${latLng.latitude}, ${latLng.longitude}",
Toast.LENGTH_LONG
).show()
}// Convert screen pixels to geographic coordinates
val latLng = mapView.screenToLatLng(screenX, screenY)Functional interface for single tap events:
fun interface OnMapClickListener {
fun onMapClick(latLng: LatLng)
}- Triggered on single tap
- Receives LatLng of tapped location
- Does not interfere with pan gestures
Functional interface for long-press events:
fun interface OnMapLongClickListener {
fun onMapLongClick(latLng: LatLng)
}- Triggered after ~500ms press
- Receives LatLng of pressed location
- Uses Android GestureDetector for reliable detection
The library automatically converts screen coordinates to geographic coordinates using Web Mercator projection:
// Internal implementation in MapController
fun screenToLatLng(screenX: Float, screenY: Float): LatLng {
val worldX = (screenX - (viewportWidth / 2f)) / scale + centerWorldX
val worldY = (screenY - (viewportHeight / 2f)) / scale + centerWorldY
return LatLng(
latitude = worldYToLat(worldY),
longitude = worldXToLon(worldX)
)
}- Single Tap - Tap anywhere on the map to see coordinates in a short toast
- Long Press - Press and hold to see coordinates in a longer toast
- Zoom Interaction - Clicks work at any zoom level
- Pan Interaction - Panning does not trigger click events
- Toast Messages - Coordinates are displayed with full precision
- Lifecycle - Listeners are cleaned up on activity destroy
OpenMapView handles touch events in this order:
- Scale gestures (pinch-to-zoom)
- Long-press detection
- Single tap detection
- Pan gestures
This ensures zoom and long-press have priority over panning.
The library uses Android's GestureDetector for reliable touch event handling:
onSingleTapConfirmed()- Fires click listener after confirming single taponLongPress()- Fires long-click listener after 500ms press- Automatically distinguishes between tap, long-press, and pan gestures
LatLng coordinates are returned as Double values with full precision:
LatLng(
latitude = 51.466123456789,
longitude = 7.249087654321
)This precision is suitable for:
- Adding markers at tapped locations
- Measuring distances between points
- Geocoding and reverse geocoding
- Route planning
- Touch event processing is highly optimized
- Coordinate conversion uses efficient Web Mercator formulas
- No performance impact on map rendering
- Listeners are called on the UI thread
mapView.setOnMapClickListener { latLng ->
mapView.addMarker(Marker(
position = latLng,
title = "Tapped Location"
))
}var firstPoint: LatLng? = null
mapView.setOnMapClickListener { latLng ->
val first = firstPoint
if (first == null) {
firstPoint = latLng
Toast.makeText(this, "Tap second point", Toast.LENGTH_SHORT).show()
} else {
val distance = calculateDistance(first, latLng)
Toast.makeText(
this,
"Distance: ${distance}m",
Toast.LENGTH_LONG
).show()
firstPoint = null
}
}mapView.setOnMapLongClickListener { latLng ->
AlertDialog.Builder(this)
.setTitle("Map Actions")
.setItems(arrayOf("Add Marker", "Share Location", "Navigate")) { _, which ->
when (which) {
0 -> addMarkerAt(latLng)
1 -> shareLocation(latLng)
2 -> startNavigation(latLng)
}
}
.show()
}// Map click listener
mapView.setOnMapClickListener { latLng ->
Toast.makeText(this, "Map clicked", Toast.LENGTH_SHORT).show()
}
// Marker click listener
mapView.setOnMarkerClickListener { marker ->
Toast.makeText(this, "Marker: ${marker.title}", Toast.LENGTH_SHORT).show()
true // Return true to consume the event
}When a marker is clicked:
- If marker listener returns
true, event is consumed (map click not fired) - If marker listener returns
false, event propagates to map click listener
Default Center: Bochum, Germany (51.4620°N, 7.2480°E) at zoom 13.0
