Select to view content in your preferred language

How do I handle the DefaultMapViewOnTouchListener.OnTouch event's Action.Up, Action.Down and Action.Move with Kotlin Maps SDK Android

1332
6
Jump to solution
05-31-2023 06:35 AM
GPK
by
New Contributor II

Hi,

Currently, I am migrating the ArcGis dependency from Runtime 100.13.1 to MapsSDK 200.1.0. Struggling with MapView's gesture handling.

With 100.x we have DefaultMapViewOnTouchListener through that the onSingleTapConfirmed and OnTouch(Up, Down, and Move) events got handled, the same onSingleTapConfirmed available as SharedFlow in 200.x but the onTouch event is not available I can see OnUp and OnDown SharedFlows but not triggering at all. Also, how do I handle OnMove event in the mapview?

UseCase: Identify the features by drawing a box on mapview via TouchListeners!

Thanks in Advance!

0 Kudos
1 Solution

Accepted Solutions
GPK
by
New Contributor II

Thanks again for the response @FPearson.

You have almost shown me a way with onUp and onDown coordinates, I can use the area of geometry and find the features that fall under it. But the visual representation on the ACTION_MOVE is still not achievable with those SharedFlows.

I found a workaround with a Transparent Temp View on top of the MapView. The  MapView and TempView should have the same layout dimensions and added the onTouchListener to the TempView. Based on the screen coordinates that I get from the TempView's touchListener converted it to Point by using mapView.screenToLocation like below. 

MotionEvent.ACTION_MOVE -> {
val p: Point? = mapView.screenToLocation(
ScreenCoordinate(event.x.toDouble(), event.y.toDouble())
)
// Plotted the envelope box here
}

 With this, the use case got achieved.

Thanks again for the valuable time, ideas, and suggestions.

View solution in original post

6 Replies
GPK
by
New Contributor II

The onSingleTapConfirmed, OnUp, and OnDown events got triggered simultaneously with separate lifecycle scopes launch like below,

lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
(mapView.onSingleTapConfirmed as? SharedFlow)?.collect {/*handle the onSingleTapConfirmed Event*/}
}
launch {
(mapView.onUp as? SharedFlow)?.collect {/*handle the onUp Event*/}
}
launch {
(mapView.onDown as? SharedFlow)?.collect {/*handle the onDown Event*/}
}
}
}

But still not sure how to handle the OnMove event when 

mapView.interactionOptions.isPanEnabled = false

  

0 Kudos
FPearson
Esri Contributor

Hi GPK, It's good that you've figured out how to collect `onSingleTapConfirmed`, `onDown` and `onUp` at the same time. To handle move events you need to subscribe to `onPan`.

You could add to your example code as follows:

launch { mapView.onPan.collect { /* handle pan/move events */ } }

Note that you don't need to cast the event to a SharedFlow in order to use it.

I believe the onPan event should work even if `isPanEnabled` is set to false.

GPK
by
New Contributor II

Hi @FPearson,

Thanks for the response.

Unfortunately, the PanChangeEvent is not worked in my case when`isPanEnabled` is set to false.

The co-ordinates it gives the top left corner point always even when I performed the OnDown action in the center of the mapView and dragged it towards the bottom right to plot a square box to identify the features that fall under the square box(envelope). But it plotted from OnDown point to the top left corner of the mapview.

I mean the panChangeEvent.motion.x and panChangeEvent.motion.y those coordinates always falls on the top left edge of Mapview instead of following the drag coordinates.

Please find the screenshot that we supported in 100.x version with DefaultMapViewOnTouchListener.

Thanks in advance.

0 Kudos
FPearson
Esri Contributor

Hi GPK,

Note that these coordinates tell you the offset from the previous pan event, not the absolute position of the event on the screen. I think this is why you are seeing lots of x and y values near zero -- this just means that the event happened very close to where the previous event happened (note that you will probably receive 100s of pan events for one pan gesture).

I think the easiest approach to creating the feature you're looking for is to use the coordinates from the `onDown` event as one corner of the envelope and the coordinates from `onUp` as the other corner. Another possibility is to add up all the x and y values that you get from `onPan` to calculate the total x and y movement and add that to the starting coordinates that you get from `onDown`. I hope that helps 🙂

GPK
by
New Contributor II

Thanks again for the response @FPearson.

You have almost shown me a way with onUp and onDown coordinates, I can use the area of geometry and find the features that fall under it. But the visual representation on the ACTION_MOVE is still not achievable with those SharedFlows.

I found a workaround with a Transparent Temp View on top of the MapView. The  MapView and TempView should have the same layout dimensions and added the onTouchListener to the TempView. Based on the screen coordinates that I get from the TempView's touchListener converted it to Point by using mapView.screenToLocation like below. 

MotionEvent.ACTION_MOVE -> {
val p: Point? = mapView.screenToLocation(
ScreenCoordinate(event.x.toDouble(), event.y.toDouble())
)
// Plotted the envelope box here
}

 With this, the use case got achieved.

Thanks again for the valuable time, ideas, and suggestions.

FPearson
Esri Contributor

Great idea -- I'm glad that you got it working 🙂