Android:ItemizedOverlay onTouchEvent 和 onTap 重叠
我试图在地图叠加层上放置一个标记,然后在用户选择可绘制对象时显示一个对话框。问题是事件似乎重叠。在我单击地图并绘制标记后,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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我遇到了完全相同的问题,我的 onTouchEvent 在地图上添加了一个标记,并希望它在用户单击它时显示有关该标记的信息,它有效,但它还在其顶部添加了另一个标记。
所以我所做的不是使用 onTouchEvent 而是在 onTap(int index) 和 onTap(Geopoint p, MapView mapView) 中执行所有操作,如下所示:
问候,
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:
Regards,
Tom
如果您要更新之前的覆盖层,请在对 `remove() 的调用中设置
isFirst=true;
以删除相关覆盖层。在
onTap()
调用中,如果在
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, useI hope that it'll work the same if
isFirst=true
is set in theonDraw()
as well.我认为问题从根本上来说是 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!