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();
}
}
3 ответа
У меня была точно такая же проблема, мой 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;
}
С Уважением,
Том
Если вы обновляете предыдущее наложение, установите isFirst=true;
в вызове `remove() для удаления рассматриваемого оверлея.
в onTap()
звоните, пользуйтесь
if(isFirst)
{
isFirst=false;
} else{
// the actual onTap() comes here
}
Я надеюсь, что это будет работать так же, если isFirst=true
установлен в onDraw()
также.
Я думаю, что проблема в основном в том, что onTap является конкретным onTouchEvent, поэтому, если вы пишете оба в оверлее, они оба запускаются, когда вы касаетесь карты
Вы можете попытаться добавить новый элемент наложения в одно из сенсорных событий, реализованных в mapActivity, и оставить событие onTap в наложении, как сейчас.
это может работать так, но вы должны попробовать, я не уверен!