16

is there a way to set a longClickListsner on a marker on google maps v2? I want to have the user long press on the marker and have a dialog show with options to delete or view information. Can this be done?

tyczj
  • 71,600
  • 54
  • 194
  • 296

8 Answers8

17

I have another proposition.

First i make the marker draggable:

mapa.addMarker(new MarkerOptions()  ...     
      .setDraggable(true);

After you can make a listener setOnMarkerDragListener like this:

mapa.setOnMarkerDragListener(new OnMarkerDragListener() {

            @Override
            public void onMarkerDragStart(Marker marker) {
                // TODO Auto-generated method stub
                //Here your code
            }

            @Override
            public void onMarkerDragEnd(Marker marker) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onMarkerDrag(Marker marker) {
                // TODO Auto-generated method stub

            }
        });

And then you can override that you want (normally onMarkerDragStart to simulate a long click)

Hope it helps

ARP
  • 531
  • 3
  • 8
  • I have tried this but my marker change position just on tap. I have not started to drag it just tap on it and it changed. I don't want to do this. Can you suggest me any other way. – Anurag Srivastava May 23 '17 at 05:23
  • I think is because the marker is centered in the point you touched. I don't know if the there is a solution for that, sorry. – ARP May 23 '17 at 17:40
14

Marker class doesn't have LongClickListener. Though this approach is far from perfect here is an idea about what you can do.

Set a long click listener for your GoogleMap object. On long click, check if the clicked position is close enough to any of your markers. To decide this closeness threshold, you may use map zoom level.

Here is the not so good sample code. I haven't tried it but it may suit your needs.

    map.setOnMapLongClickListener(new OnMapLongClickListener() {

            @Override
            public void onMapLongClick(LatLng latLng) {
                for(Marker marker : yourMarkerList) {
                    if(Math.abs(marker.getPosition().latitude - latLng.latitude) < 0.05 && Math.abs(marker.getPosition().longitude - latLng.longitude) < 0.05) {
                        Toast.makeText(MapActivity.this, "got clicked", Toast.LENGTH_SHORT).show(); //do some stuff
                        break;
                    }
                }

            }
        });
akaya
  • 1,140
  • 9
  • 27
  • That would be one way but its not fool proof because you could select a marker you dont want and you wont know until you delete it – tyczj Mar 13 '13 at 18:50
  • @tyczj Yes, it is not foul proof. Still, even if marker had a listener, misclicks would have occurred when they are too close. Imo, checking for closest marker doesn't bring extra problems. Misclicks occur anyway, you just need make user confirm the operation. – akaya Mar 14 '13 at 08:05
  • It seems to be not working with a big amount of points nearby because of thickness of finger and zoom of the map – Vlad Dec 11 '18 at 14:02
  • the difference should be in "screen pixels" instead of latitude.. – M. Usman Khan Mar 22 '20 at 18:11
7

As ARP suggested, you can use the OnMarkerDragListener to simulate the long click. In my case, I am creating new markers when the onMapLongClick() occurred, so I wanted to do something similar (but not equal) that the

@Override
public void onMarkerDragStart(Marker marker) {
    marker.remove();
    MarkerOptions options = createBasedOnMarker(marker);
    this.googleMap.addMarker(options);
}

this way, you will remove the marker that was previously within the map and create another in the same position, with the same content (you have to have a Map or Pair to keep the info from the markers you create).

Hope my workaround helps.

DanihelSan
  • 96
  • 1
  • 2
3

ARPs answer is fine, but it suffers from a ugly effect: the marker shifts up when you start dragging and when you finish the marker is still in a higher position than you are pointing with your finger.

Have a look to http://www.youtube.com/watch?v=RxAHHJD4nU8

user2928048
  • 3,940
  • 2
  • 12
  • 12
3

akaya's answer isn't a bad approach, but if you have the com.google.maps.android:android-maps-utils:0.3+ library included with your project you can be exact about the distance:

double distance = SphericalUtil.computeDistanceBetween( 
    marker.getPosition(), 
    latLng 
);
if( distance < 50 ) { // closer than 50 meters?
    //..do stuff..
}
Community
  • 1
  • 1
flowtron
  • 854
  • 7
  • 20
3

Hey Take a look at this code I have just stopped the marker from getting dragged and used the onMarkerDragStart 's long click detection.

public abstract class LinkMarkerLongClickListener implements GoogleMap.OnMarkerDragListener {

    private int previousIndex = -1;

    private Marker cachedMarker = null;
    private LatLng cachedDefaultPostion = null;

    private List<Marker> markerList;
    private List<LatLng> defaultPostions;

    public LinkMarkerLongClickListener(List<Marker> markerList){
        this.markerList = new ArrayList<>(markerList);
        defaultPostions = new ArrayList<>(markerList.size());
        for (Marker marker : markerList) {
            defaultPostions.add(marker.getPosition());
            marker.setDraggable(true);
        }
    }

    public abstract void onLongClickListener(Marker marker);

    @Override
    public void onMarkerDragStart(Marker marker) {
        onLongClickListener(marker);
        setDefaultPostion(markerList.indexOf(marker));
    }

    @Override
    public void onMarkerDrag(Marker marker) {
        setDefaultPostion(markerList.indexOf(marker));
    }

    @Override
    public void onMarkerDragEnd(Marker marker) {
        setDefaultPostion(markerList.indexOf(marker));
    }


    private void setDefaultPostion(int markerIndex) {
        if(previousIndex == -1 || previousIndex != markerIndex){
            cachedMarker = markerList.get(markerIndex);
            cachedDefaultPostion = defaultPostions.get(markerIndex);
            previousIndex = markerIndex;
        }
        cachedMarker.setPosition(cachedDefaultPostion);
    }
}

Your can call the listener like this !

map.setOnMarkerDragListener(new LinkMarkerLongClickListener(markers) {
            @Override
            public void onLongClickListener(Marker marker) {
                ToastUtils.showToast(Mission1Activity.this, marker.getTitle());
            }
        });
jknair0
  • 1,194
  • 13
  • 24
  • When I do this, it seems that my user is still able to drag the marker around on the screen. Is there a fix to this? – cwbusacker Dec 14 '18 at 01:39
0

Just in case someone may need it, I have adjusted a logarithmic function to calculate the closeness threshold @akaya mentioned, which works fine for zooms between 5.0 and 18. Here is the function:

float zoom = mMap.getCameraPosition().zoom;
double maxDistance = 2000000 * Math.exp(-0.644*zoom);
Tragalunas
  • 311
  • 2
  • 6
0

Here is a simple working solution. We need to use screen xy to check distance.

googleMap.setOnMapLongClickListener{ loc ->
                var distance = 10000
                var nearestMarker: Marker? = null
                allBcmMarkers.forEach { mrkr ->
                    googleMap?.projection?.let { prj ->
                        val tapXY = prj.toScreenLocation(loc)
                        val mrkrXY = prj.toScreenLocation(mrkr.position)
                        val THRESH = 50
                        val xDiff = abs(tapXY.x - mrkrXY.x)
                        val yDiff = abs(tapXY.y - mrkrXY.y)
                        if (xDiff < THRESH && yDiff < THRESH) {
                            val mrkrDist =
                                sqrt((xDiff * xDiff + yDiff * yDiff + xDiff * yDiff).toDouble())
                            if (mrkrDist < distance) {
                                distance = mrkrDist.toInt()
                                nearestMarker = mrkr
                            }
                        }
                    }
                }

                // you have nearestMarker
        }
    }
M. Usman Khan
  • 3,689
  • 1
  • 59
  • 69