【问题标题】:Android: ItemizedOverlay onTouchEvent and onTap overlappingAndroid:ItemizedOverlay onTouchEvent 和 onTap 重叠
【发布时间】:2011-06-25 16:45:28
【问题描述】:

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

}

【问题讨论】:

    标签: android android-mapview touch-event overlayitem


    【解决方案1】:

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

    问候,

    汤姆

    【讨论】:

    • 那你怎么得到这个的索引呢?
    • @LeeArmstrong 我在 onTap(int index) 中显示一个视图(该视图在叠加层中是私有的),如果它可见,则在另一个 onTap 中关闭该视图
    • 我使用了一个全局变量来存储我的索引。
    • if(Tapped) 不起作用。我在覆盖层内部或外部单击它总是错误的。
    【解决方案2】:

    如果您要更新之前的覆盖,请在调用 `remove() 时设置 isFirst=true; 以删除有问题的覆盖。

    onTap() 调用中,使用

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

    如果isFirst=true 也设置在onDraw() 中,我希望它也能正常工作。

    【讨论】:

      【解决方案3】:

      我认为问题的根本在于 onTap 是一个特定的 onTouchEvent,因此如果您在叠加层中同时写入两者,它们都会在您触摸地图时被触发

      您可以尝试在您在 mapActivity 中实现的触摸事件之一中添加一个新的叠加项目,并将 onTap 事件保留在叠加中,就像现在一样

      它可能会这样工作,但你必须尝试,我不确定!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-18
        • 2013-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-05
        • 1970-01-01
        相关资源
        最近更新 更多