Android:ItemizedOverlay onTouchEvent 和 onTap 重叠

发布于 2024-10-16 21:58:09 字数 5009 浏览 6 评论 0原文

我试图在地图叠加层上放置一个标记,然后在用户选择可绘制对象时显示一个对话框。问题是事件似乎重叠。在我单击地图并绘制标记后,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();
    }

}

I am trying to place a marker on a map overlay and then present a dialog when the user selects the drawable. The problem is the events seem to overlap. After I click the map and the marker is drawn, the onTap fires immediately afterwards, and because I have just drawn the marker, it is directly under the onTap event, so my dialog always fires. Does anyone have any suggestions on how to make these events mutually exclusive?

Here is the code for the map activity:

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;
    }
}

and the code for the overlay class:

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();
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

任性一次 2024-10-23 21:58:09

我遇到了完全相同的问题,我的 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

I had exactly the same issue, my onTouchEvent added a marker to a map, and wanted it to show information about that marker when the user clicks on it, it worked but it also added another marker on top of it.

So what I did was not use onTouchEvent but do everything in onTap(int index) and onTap(Geopoint p, MapView mapView) like so:

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;
}

Regards,

Tom

紫﹏色ふ单纯 2024-10-23 21:58:09

如果您要更新之前的覆盖层,请在对 `remove() 的调用中设置 isFirst=true; 以删除相关覆盖层。

onTap() 调用中,

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

如果在 onDraw() 中设置 isFirst=true,我希望它会发挥相同的作用:出色地。

If you are updating the previous overlay, set isFirst=true; in the call to `remove() to remove the overlay in question.

In the onTap() call, use

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

I hope that it'll work the same if isFirst=true is set in the onDraw() as well.

枕头说它不想醒 2024-10-23 21:58:09

我认为问题从根本上来说是 onTap 是一个特定的 onTouchEvent,因此如果您在覆盖中写入两者,当您触摸地图时它们都会被触发

您可以尝试在您实现的触摸事件之一中添加一个新的覆盖项目你的mapActivity并将onTap事件留在叠加层中,因为现在

它可能会以这种方式工作,但你必须尝试,我不确定!

I think that the problem is fundamentally that the onTap is a particular onTouchEvent, so if you write both in the overlay they are both fired when you touch the map

You could try to add a new overlay item in one of the touch events you implemented in your mapActivity and leave the onTap event in the overlay as it is right now

it might work this way but you have to try, I'm not sure!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文