Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Map Marker on Longpress is Plotted Below the Area That is Actually LongPressed (on API 15)

I have been racking my brains for days now on this and have Googled and SO'ed but can't seem to find anyone else reporting such problem(could have missed it).

I have a customized Mapview Class that listens for longpress among others and am using it to plot markers on my map. It plots okay on API-8. But on API-15 the marker is offsetted by about 2cm below where the user finger is doing the longpress. This is observed for both actual device (samsung s2) and eclipse emulator. Also the finger area long-pressed versus the marker area plotted(offset by about 2cm) is observed on all zoom levels.

Here is my customized Mapview Class (yanked it from somewhere):

public class MyCustomMapView extends MapView {
public interface OnLongpressListener {
    public void onLongpress(MapView view, GeoPoint longpressLocation);
}

static final int LONGPRESS_THRESHOLD = 500;
private GeoPoint lastMapCenter;

private Timer longpressTimer = new Timer();
private MyCustomMapView.OnLongpressListener longpressListener;


public MyCustomMapView(Context context, String apiKey) {
    super(context, apiKey);
}

public MyCustomMapView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public MyCustomMapView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public void setOnLongpressListener(MyCustomMapView.OnLongpressListener listener) {
    longpressListener = listener;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    handleLongpress(event);

    return super.onTouchEvent(event);
}

private void handleLongpress(final MotionEvent event) {

    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        // Finger has touched screen.
        longpressTimer = new Timer();
        longpressTimer.schedule(new TimerTask() {
            @Override
            public void run() {

                GeoPoint longpressLocation = getProjection().fromPixels((int)event.getX(), (int)event.getY());

                /*
                 * Fire the listener. We pass the map location
                 * of the longpress as well, in case it is needed
                 * by the caller.
                 */
                longpressListener.onLongpress(MyCustomMapView.this, longpressLocation);
            }

        }, LONGPRESS_THRESHOLD);

        lastMapCenter = getMapCenter();
    }

    if (event.getAction() == MotionEvent.ACTION_MOVE) {

        if (!getMapCenter().equals(lastMapCenter)) {
            // User is panning the map, this is no longpress
            longpressTimer.cancel();
        }

        lastMapCenter = getMapCenter();
    }

    if (event.getAction() == MotionEvent.ACTION_UP) {
        // User has removed finger from map.
        longpressTimer.cancel();
    }

        if (event.getPointerCount() > 1) {
                    // This is a multitouch event, probably zooming.
            longpressTimer.cancel();
        }
}

And this is how I call the Class above:

custom_marker = getResources().getDrawable(R.drawable.marker3);
custom_marker.setBounds(-custom_marker.getIntrinsicWidth(), -custom_marker.getIntrinsicHeight(), 0, 0);
customSitesOverlay = new CustomSitesOverlay(custom_marker);
mapView.getOverlays().add(customSitesOverlay);
customSitesOverlay.addOverlay(new OverlayItem(longpressLocation, "User Marker", id));
like image 532
Marka A Avatar asked Nov 12 '22 21:11

Marka A


1 Answers

It looks like a setBounds problem. You are setting the marker bounds to center in the bottom-right corner of drawable. Is that the intented behaviour?

You can set the marker to center in the bottom-center (which is the most usual type or markers) setting the bounds to:

custom_marker.setBounds(-custom_marker.getIntrinsicWidth()/2, -custom_marker.getIntrinsicHeight(), custom_marker.getIntrinsicWidth()/2, 0); 

good luck.

like image 189
Luis Avatar answered Nov 15 '22 12:11

Luis