Android: ItemizedOverlay onTouchEvent и onTap перекрываются - PullRequest
3 голосов
/ 11 февраля 2011

Я пытаюсь поместить маркер на оверлей карты, а затем отображаю диалоговое окно, когда пользователь выбирает чертеж. Проблема в том, что события, похоже, частично совпадают. После того, как я щелкну карту и маркер будет нарисован, onTap запускается сразу после этого, и поскольку я только что нарисовал маркер, он находится непосредственно под событием onTap, поэтому мой диалог всегда срабатывает. У кого-нибудь есть предложения, как сделать эти события взаимоисключающими?

Вот код активности карты:

public class SelectGameLocation extends MapActivity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener  {

    private MapView mapView = null;
    private SelectGameLocationItemizedOverlay selectLocationOverlay = null;
    private List<Overlay> mapOverlays = null;
    private GestureDetector gestureDetector = null;

    @Override
    protected void onCreate(Bundle arg0) {
        super.onCreate(arg0);

        //set the layout
        setContentView(R.layout.activity_select_game_location);

        //configure activity for double clicks
        gestureDetector = new GestureDetector(this);
        gestureDetector.setOnDoubleTapListener(this);

        //create and configure mapview
        mapView = (MapView) findViewById(R.id.selectGameLocation);
        mapView.setBuiltInZoomControls(true);
        mapView.setHapticFeedbackEnabled(true);

        //configure the overlay to draw the icons on the map
        mapOverlays = mapView.getOverlays();
        Drawable drawable = this.getResources().getDrawable(R.drawable.map_icon);
        selectLocationOverlay = new SelectGameLocationItemizedOverlay(drawable, this);
        mapOverlays.add(selectLocationOverlay);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        gestureDetector.onTouchEvent(ev);
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onDoubleTap(MotionEvent me) {
        GeoPoint p = GeoPointHelper.getPointClicked(me, mapView);
        mapView.getController().animateTo(p);
        mapView.getController().zoomIn();
        return true;
    }

    //Overridden methods but not used
    @Override
    public boolean onDoubleTapEvent(MotionEvent me) {
        return false;
    }

    @Override
    public boolean onDown(MotionEvent me) {
        return false;
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e) {
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent me) {
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        return false;
    }

    @Override
    public boolean onSingleTapUp(MotionEvent me) {
        return false;
    }
}

и код класса оверлея:

public class SelectGameLocationItemizedOverlay extends ItemizedOverlay {

    private Context context = null;
    private List<OverlayItem> overlays = new ArrayList<OverlayItem>();

    public SelectGameLocationItemizedOverlay(Drawable marker, Context context) {
        super(boundCenterBottom(marker));
        this.context = context;
    }

    @Override
    protected boolean onTap(int index) {

        OverlayItem itemClicked = overlays.get(index);
        AlertDialog.Builder dialog = new AlertDialog.Builder(context);
        dialog.setTitle(itemClicked.getTitle());
        dialog.setMessage(itemClicked.getSnippet());
        dialog.setCancelable(true);
        dialog.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                Log.i(this.getClass().getName(), "Selected Yes To Add Location");
                ((SelectGameLocation) context).finish();
            }
        });
        dialog.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                Log.i(this.getClass().getName(), "Selected No To Add Location");
                dialog.cancel();
            }
        });
        dialog.show();
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent me, MapView mapView) {
        drawMarker(GeoPointHelper.getPointClicked(me, mapView));
        return super.onTouchEvent(me, mapView);
    }

    private OverlayItem drawMarker(GeoPoint p) {        
            OverlayItem overlayitem = new OverlayItem(p, "Select As Game Location?", "Do you want this location to be added as the location for the game?");
            getOverlays().clear();
            addOverlay(overlayitem);
            return overlayitem;
    }

    public List<OverlayItem> getOverlays() {
        return overlays;
    }

    public void addOverlay(OverlayItem overlay) {
        overlays.add(overlay);
        populate();
    }

    @Override
    protected OverlayItem createItem(int i) {
        return overlays.get(i);
    }

    @Override
    public int size() {
        return overlays.size();
    }

}

Ответы [ 3 ]

8 голосов
/ 24 марта 2011

У меня была точно такая же проблема, мой onTouchEvent добавил маркер на карту и хотел, чтобы он отображал информацию об этом маркере, когда пользователь нажимает на него, он работал, но он также добавил еще один маркер поверх него.

Так что я не использовал onTouchEvent, а делал все в onTap (int index) и onTap (Geopoint p, MapView mapView) примерно так:

public boolean onTap (final GeoPoint p, final MapView mapView){
    boolean tapped = super.onTap(p, mapView);
    if (tapped){            
        //do what you want to do when you hit an item           
    }           
    else{
        //do what you want to do when you DON'T hit an item
        }                   
    return true;
}

//Return true in order to say that the listener has correctly taken the event into account 
@Override
protected boolean onTap(int index) {
    return true;
}

С уважением,

Tom

1 голос
/ 09 декабря 2012

Если вы обновляете предыдущее наложение, установите isFirst=true; в вызове на `remove () для удаления рассматриваемого наложения.

В вызове onTap() используйте

if(isFirst)
{
    isFirst=false;
} else{
    // the actual onTap() comes here
}

Я надеюсь, что он будет работать так же, если в onDraw() также будет установлен isFirst=true.

0 голосов
/ 11 февраля 2011

Я думаю, что проблема в основном в том, что onTap является конкретным onTouchEvent, поэтому, если вы пишете оба в оверлее, они оба запускаются при касании карты

Вы можете попытаться добавить новый элемент наложения в одно из сенсорных событий, реализованных в mapActivity, и оставить событие onTap в наложении таким, как оно есть сейчас

это может сработать, но вы должны попробовать, я не уверен!

...