Closed tobrun closed 5 years ago
A workaround would at least be to provide a MapView.OnMoveListener
with a onMove
callback. The callback would typically be called if the view detecs a MotionEvent.ACTION_MOVE
event and the event is not dispatched as a scroll event. This happens e.g. after a long-press followed by a drag.
We are currently working on an Android Map Editor using mapbox-gl-native as the framework. However, I see no possibilities for detecting when the user tries to move a marker. With the above workaround we could detect a long-press followed by a move event and then move the marker by recreating it in the new position.
@pshustad It is possible to add your own onTouch
listener to MapView
from an activity since it inherits that from View
.
We used this as a work around to detect long presses until we had a chance to add a long press listener.
@ljbade Thanks for the advice. I was actually in the middle of preparing a pull request for a full-blown implementation of the OnMarkerDragListener
API, but might try this workaround instead.
Of course, if there are future plans for a Mapbox "drag marker" API, I would be happy to continue working on it.
@pshustad feel free to keep working on a PR if you want. I just wanted to let you know about the work around.
Now that #3276 has landed this feature can be implemented using View Markers instead of GL Markers
Hi @tobrun , could you please elaborate how you would realize draggable markers with marker views? (I was looking for a possibility to add a touch listener to a marker view but could not find any.)
I'm also interested how to drag Markers same way as it is possible in Google Maps. @tobrun please give us some suggestions or code snippet how you thought to implement it using View Markers. What are the development plans in this area?
@p-fischer @filipc at this point I haven't started to think about the actual implementation or haven't discussed this internally. This feature just barely didn't make the cut for the 4.1.0
feature list and was considered a nice to have. @frederoni is working on the iOS equivalent in https://github.com/mapbox/mapbox-gl-native/pull/5373.
Ideally I would love to support the multi window drag/drop functionality as shown at Google I/O this year. This will require us to use the Android SDK drag and drop and not create something custom from scratch. At this point, when a drag starts we probably need to call removeMarker
and re-add it again when we drop the marker.
I hope this will become sooner, My legacy mapbox android have draggable marker, I dont want to change/remove it from this current mapbox sdk
@tobrun @ljbade Is there any documentation or experiment PR on how to implement Draggable Marker using ACTION_MOVE touch event? I used to extend ItemizedIconOverlay and override onDrawItem to achieve this in 0.7.4. Any help will be much appreciated! Thanks :)
This issue is blocked by #5639, that PR will move the touch logic in core instead of the Android binding. This will introduce the requirement of implementing draggable markers in a different way as initially indicated in https://github.com/mapbox/mapbox-gl-native/issues/2450#issuecomment-228201350.
Current thinking:
It is almost 1AM here and I am spending hours trying to find a way to drag a marker. My current application uses the JavaScript flavour and dragging works quite well. However, there is a demand for native Android app and it's being hard to get it implemented. Hope this get some priority in your team, thank you!
This is on my todo list for improvements to MarkerViews. Currently working on zIndex, this will be the next item on the list.
Hi, any update on this issue? Regards.
+1
One kinda hacky way that I've found of doing this is to use reflection and set an onTouch listener for the MapView. I think this might interfere with the onClick for Markers, but I haven't tested. Furthermore, this behavior does not wait for a long press to start dragging (this is the behavior I wanted, but it may not be appropriate for all cases)
mapView.setOnTouchListener(new View.OnTouchListener() {
//This onTouch code is a copy of the MapView#onSingleTapConfirmed code, except I'm dragging instead of clicking, and it's being called for every touch event rather than just a tap
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event != null) {
PointF tapPoint = new PointF(event.getX(), event.getY());
float toleranceSides = 4 * screenDensity;
float toleranceTopBottom = 10 * screenDensity;
float averageIconWidth = 42;
float averageIconHeight = 42;
RectF tapRect = new RectF((tapPoint.x - averageIconWidth / 2 - toleranceSides) / screenDensity,
(tapPoint.y - averageIconHeight / 2 - toleranceTopBottom) / screenDensity,
(tapPoint.x + averageIconWidth / 2 + toleranceSides) / screenDensity,
(tapPoint.y + averageIconHeight / 2 + toleranceTopBottom) / screenDensity);
try {
Method method = mapView.getClass().getDeclaredMethod("getMarkersInRect", RectF.class); //Using reflection to access a Mapbox Package Private method
method.setAccessible(true);
List<Marker> nearbyMarkers = (List<Marker>) method.invoke(mapView, tapRect);
long newSelectedMarkerId = -1;
List<Marker> selectedMarkers = map.getSelectedMarkers();
if (nearbyMarkers != null && nearbyMarkers.size() > 0) {
Collections.sort(nearbyMarkers);
for (Marker nearbyMarker : nearbyMarkers) {
boolean found = false;
for (Marker selectedMarker : selectedMarkers) {
if (selectedMarker.equals(nearbyMarker)) {
found = true;
}
}
if (!found) {
newSelectedMarkerId = nearbyMarker.getId();
break;
}
}
}
if (newSelectedMarkerId >= 0) {
List<Annotation> annotations = map.getAnnotations();
int count = annotations.size();
for (int i = 0; i < count; i++) {
Annotation annotation = annotations.get(i);
if (annotation instanceof MarkerView) {
if (annotation.getId() == newSelectedMarkerId) {
if (selectedMarkers.isEmpty() || !selectedMarkers.contains(annotation)) {
//DRAG! instead of clicking
annotation.setPosition(map.getProjection().fromScreenLocation(tapPoint));
return true;
}
break;
}
}
}
}
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
return false;
}
});
@tobrun Any plans to have draggable markers in 5.0?
Hi, Any update on for the draggable marker feature? Thanks :)
Android : any update or trick we use drag marker or point or polyline on map??? i am stuck for four three days on drag marker or point on polyline??? kindly help me to solve out this problem or code??
@Meerz Refer to the code I posted a few comments above. I can confirm it is still working on Mapbox 6.0.1
@tobrun Is this feature in any future roadmap?
@vanshg thansk for quick reply i implement but here map.getSelectedMarkers(); and screenDensity cannot resolve??map not resolve annotation.setPosition(map. this also
@Meerz You will need to adjust the code I posted to match what you've named your variables. In this case, map
refers to the MapboxMap
instance. You can set screenDensity
equal to getResources().getDisplayMetrics().density;
Also, I believe I spoke too soon. The code I posted earlier may need a couple other modifications to work. You should be able to get rid of reflection and get rid of the try-catch
(replace the reflection code with List<MarkerView> nearbyMarkers = map.getMarkerViewsInRect(tapRect);
@vanshg yes, this is going to be implemented when we revamp the annotations api.
@tobrun Have you decided on the tentative release date after revamping the annotation api?
@tobrun any upadates regarding draggable marker???
An example how to do this with SymbolLayer in #12326
Draggable markers, and annotations in general, support has been added to the Annotation Plugin in the v0.3.0
, see https://github.com/mapbox/mapbox-plugins-android/pull/753.
Feel free to check out the plugin and let us know what you think, thanks!
/cc @chloekraw
Annotations are deprecated and are replaced by the annotations plugin. Support for dragging annotations is already implemented.
Google Maps allows its Markers to be draggable and allows end developers to register to events