Event Handlers
MapConductor provides comprehensive event handling for user interactions with the map and its components. All events are handled through the MapViewContainer component.
All event listeners are passed through MapView component.
MapView( ..., onMapLoaded: OnMapLoadedHandler? = null, onMapClick: OnMapEventHandler? = null, onCameraMoveStart: OnCameraMoveHandler? = null, onCameraMove: OnCameraMoveHandler? = null, onCameraMoveEnd: OnCameraMoveHandler? = null, onMarkerClick: OnMarkerEventHandler? = null, onMarkerDragStart: OnMarkerEventHandler? = null, onMarkerDrag: OnMarkerEventHandler? = null, onMarkerDragEnd: OnMarkerEventHandler? = null, onMarkerAnimateStart: OnMarkerEventHandler? = null, onMarkerAnimateEnd: OnMarkerEventHandler? = null, onCircleClick: OnCircleEventHandler? = null, onPolylineClick: OnPolylineEventHandler? = null, onPolygonClick: OnPolygonEventHandler? = null, onGroundImageClick: OnGroundImageEventHandler? = null,) { }Map Events
Section titled “Map Events”Map Initialization
Section titled “Map Initialization”-
Called when the map has finished loading and is ready for interaction.
onMapLoaded: OnMapLoadedHandler? = null -
Example
MapView(...onMapLoaded: {println("Map loaded")},) {...}
Map Interaction
Section titled “Map Interaction”-
Called when the user taps on the map (not on any overlay).
onMapClick: OnMapEventHandler? = null
Event Data: GeoPoint - the geographic coordinates of the tap
- Example
MapView(...onMapClick = { geoPoint ->println("Map clicked at: ${geoPoint.latitude}, ${geoPoint.longitude}")}) {...}
Marker Events
Section titled “Marker Events”All marker events receive a MarkerState object containing the marker’s current state.
Click Events
Section titled “Click Events”-
Called when a marker is tapped.
onMarkerClick: OnMarkerEventHandler? = null -
Example
MapView(...onMarkerClick = { markerState ->println("Marker clicked at: ${geoPoint.latitude}, ${geoPoint.longitude}")},) {...}
Drag Events
Section titled “Drag Events”-
onMarkerDragStart: Called when dragging begins -
onMarkerDrag: Called continuously during dragging -
onMarkerDragEnd: Called when dragging endsonMarkerDragStart: OnMarkerEventHandler? = nullonMarkerDrag: OnMarkerEventHandler? = nullonMarkerDragEnd: OnMarkerEventHandler? = nullMapView(...onMarkerDragStart = { draggedMarker ->println("Drag started: ${draggedMarker.id}")},onMarkerDrag = { draggedMarker ->if (draggedMarker.id == markerState.id) {markerState = markerState.copy(position = draggedMarker.position)}},onMarkerDragEnd = { draggedMarker ->println("Drag ended: ${draggedMarker.id}")},) { }
Animation Events
Section titled “Animation Events”- Called when marker animations start and end.
onMarkerAnimateStart: OnMarkerEventHandler? = nullonMarkerAnimateEnd: OnMarkerEventHandler? = null
Overlay Events
Section titled “Overlay Events”Circle Events
Section titled “Circle Events”-
Called when a circle is tapped.
onCircleClick: OnCircleEventHandler? = nullEvent Data:
CircleEventdata class CircleEvent(val state: CircleState,val clicked: GeoPoint) -
example
MapView(...onCircleClick = { event ->println("A circle clicked at: ${event.clicked.latitude}, ${event.clicked.longitude}")event.state.fillColor = Color.Red.copy(opacity = 0.7f,)},) { }
Polyline Events
Section titled “Polyline Events”-
Called when a polyline is tapped.
onPolylineClick: OnPolylineEventHandler? = nullEvent Data:
PolylineEventdata class PolylineEvent(val state: PolylineState,val clicked: GeoPoint) -
example
MapView(...onPolylineClick = { event ->println("A circle clicked at: ${event.clicked.latitude}, ${event.clicked.longitude}")event.state.fillColor = Color.Red.copy(opacity = 0.7f,)},) { }
Polygon Events
Section titled “Polygon Events”onPolygonClick: OnPolygonEventHandler? = nullEvent Data: PolygonEvent
data class PolygonEvent( val state: PolygonState, val clicked: GeoPoint?)GroundImage Events
Section titled “GroundImage Events”onGroundImageClick: OnGroundImageEventHandler? = nullEvent Data: GroundImageEvent
data class GroundImageEvent( val state: GroundImageState, val clicked: GeoPointImpl?)Usage Examples
Section titled “Usage Examples”Basic Event Handling
Section titled “Basic Event Handling”// Replace MapView with your chosen map provider, such as GoogleMapView, MapboxMapViewMapView( state = mapViewState, onMapClick = { geoPoint -> println("Map clicked at: ${geoPoint.latitude}, ${geoPoint.longitude}") }, onMarkerClick = { markerState -> println("Marker clicked: ${markerState.extra}") }, onCircleClick = { circleEvent -> println("Circle clicked: ${circleEvent.state.extra}") }) { // Map content}Advanced Event Handling
Section titled “Advanced Event Handling”@Composablefun AdvancedEventHandlingExample() { var selectedItem by remember { mutableStateOf<String?>(null) } var draggedMarker by remember { mutableStateOf<MarkerState?>(null) }
// Replace MapView with your chosen map provider, such as GoogleMapView, MapboxMapViewMapView( state = mapViewState, onMapClick = { geoPoint -> selectedItem = null println("Map clicked at: $geoPoint") }, onMarkerClick = { markerState -> selectedItem = "Marker: ${markerState.extra}" }, onMarkerDragStart = { markerState -> draggedMarker = markerState println("Started dragging: ${markerState.id}") }, onMarkerDrag = { markerState -> draggedMarker = markerState println("Dragging to: ${markerState.position}") }, onMarkerDragEnd = { markerState -> draggedMarker = null println("Finished dragging: ${markerState.id}") }, onCircleClick = { circleEvent -> selectedItem = "Circle: ${circleEvent.state.extra}" }, onPolylineClick = { polylineEvent -> selectedItem = "Polyline: ${polylineEvent.state.extra}" }, onPolygonClick = { polygonEvent -> selectedItem = "Polygon: ${polygonEvent.state.extra}" } ) { // Map components }
// Show selected item info selectedItem?.let { item -> Card(modifier = Modifier.padding(16.dp)) { Text(item, modifier = Modifier.padding(16.dp)) } }}Conditional Event Handling
Section titled “Conditional Event Handling”@Composablefun ConditionalEventExample() { var editMode by remember { mutableStateOf(false) } var selectedMarkers by remember { mutableStateOf<Set<String>>(emptySet()) }
// Replace MapView with your chosen map provider, such as GoogleMapView, MapboxMapViewMapView( state = mapViewState, onMapClick = { geoPoint -> if (editMode) { // Add new marker in edit mode addNewMarker(geoPoint) } else { // Clear selection in view mode selectedMarkers = emptySet() } }, onMarkerClick = { markerState -> if (editMode) { // Toggle selection in edit mode selectedMarkers = if (markerState.id in selectedMarkers) { selectedMarkers - markerState.id } else { selectedMarkers + markerState.id } } else { // Show info in view mode showMarkerInfo(markerState) } }, onMarkerDragStart = { markerState -> if (!editMode) { // Prevent dragging in view mode return@MapViewContainer } } ) { // Map content }}Event Debouncing
Section titled “Event Debouncing”@Composablefun DebouncedEventExample() { var searchLocation by remember { mutableStateOf<GeoPoint?>(null) }
// Debounce search to avoid excessive API calls LaunchedEffect(searchLocation) { searchLocation?.let { location -> delay(500) // Wait 500ms performLocationSearch(location) } }
// Replace MapView with your chosen map provider, such as GoogleMapView, MapboxMapViewMapView( state = mapViewState, onMapClick = { geoPoint -> searchLocation = geoPoint } ) { searchLocation?.let { location -> Marker( position = location, icon = DefaultIcon( fillColor = Color.Blue, label = "🔍" ) ) } }}Multi-touch Gesture Events
Section titled “Multi-touch Gesture Events”@Composablefun GestureEventExample() { var gestureInfo by remember { mutableStateOf("No gesture") }
// Replace MapView with your chosen map provider, such as GoogleMapView, MapboxMapViewMapView( state = mapViewState, onMapClick = { geoPoint -> gestureInfo = "Single tap at: $geoPoint" }, // Note: Long press and other gestures would be handled // through the underlying map provider's gesture system ) { // Display gesture info Text( text = gestureInfo, modifier = Modifier .background(Color.Black.copy(alpha = 0.7f)) .padding(8.dp), color = Color.White ) }}Event Handler Types
Section titled “Event Handler Types”OnMapEventHandler
Section titled “OnMapEventHandler”- Definition
typealias OnMapEventHandler = (GeoPoint) -> Unit
typealias OnMarkerEventHandler = (MarkerState) -> Unittypealias OnCircleEventHandler = (CircleEvent) -> Unittypealias OnPolylineEventHandler = (PolylineEvent) -> Unittypealias OnPolygonEventHandler = (PolygonEvent) -> Unittypealias OnGroundImageEventHandler = (GroundImageEvent) -> UnitBest Practices
Section titled “Best Practices”- Performance: Avoid heavy computations in event handlers
- State Updates: Use event handlers to update your application state
- User Feedback: Provide immediate visual feedback for user interactions
- Error Handling: Handle potential null values and edge cases
- Debouncing: Debounce rapid events like dragging to improve performance
- Conditional Logic: Use application state to determine event behavior
- Event Propagation: Be aware that some events may bubble up or be consumed