如何在执行触摸事件时检测到您正在传递的视图?

时间:2010-12-01 03:57:59

标签: android events views touch

如果我将视图从一个ViewGroup移动到另一个ViewGroup,我想知道如何检测子视图,特别是在执行触摸事件时。有没有一种方法我可以打电话让我知道我正在“徘徊”哪些观点?

我现在正在做的是当我在我的视图中检测到ACTION_MOVE事件时,我将其提升到顶级父级,以便它可以移动并在整个窗口内绘制(而不仅仅是在其原始父级内部)边界),然后我想将视图移动到另一个ViewGroup,并在ACTION_UP上将视图附加到该ViewGroup。

4 个答案:

答案 0 :(得分:5)

受到Ami的响应的启发,但发现MotionEvent#getX()/ getY()以及View#getTop()/ etc返回父视图的坐标,我最后在屏幕坐标下操作以下内容,允许我在ViewGroups中工作:

        private boolean inRegion(float x, float y, View v) {
            v.getLocationOnScreen(mCoordBuffer);
            return mCoordBuffer[0] + v.getWidth() > x &&    // right edge
                   mCoordBuffer[1] + v.getHeight() > y &&   // bottom edge
                   mCoordBuffer[0] < x &&                   // left edge
                   mCoordBuffer[1] < y;                     // top edge
        }

在OnTouchListener中的用法是例如:

        boolean inside = inRegion(event.getRawX(), event.getRawY(), targetView);

答案 1 :(得分:4)

我想我找到了一种更简单的方法。

  1. 创建可能目标的ArrayList
  2. 从触摸事件中调用此方法,提供目标列表和指示符
  3. private View findView(float x, float y, ArrayList<View> targets)
    {
        final int count = targets.size();
        for (int i = 0; i < count; i++) {
            final View target = targets.get(i);
            if (target.getRight() > x && target.getTop() < y
                    && target.getBottom() > y && target.getLeft() < x) {
                return target;
            }
        }
        return null;
    }
    

答案 2 :(得分:3)

我发现塞巴斯蒂安·罗斯的回答对资源非常有帮助,但由于这不是我的问题的答案,我想我会分享我的想法。

这是我用来在屏幕上给定坐标的情况下检测视图(仅接受放置的视图)的代码。

            private DropView findDropTarget( int x, int y, int[] dropCoordinates ){
                final Rect r = mRectTemp;
                final ArrayList<DropView> dropTargets = ((main) context).getBoardDropTargets();
                final int count = dropTargets.size();
                for (int i=count-1; i>=0; i--) {
                    final DropView target = dropTargets.get(i);
                    target.getHitRect(r);
                    target.getLocationOnScreen(dropCoordinates);
                    r.offset(dropCoordinates[0] - target.getLeft(), dropCoordinates[1] - target.getTop());
                    if (r.contains(x, y)) {
                        dropCoordinates[0] = x - dropCoordinates[0];
                        dropCoordinates[1] = y - dropCoordinates[1];
                        return target;
                    }
                }
           }

好的,首先关闭mRectTemp只是一个分配的Rectangle,所以你不必继续创建新的(I.E. final Rect r = new Rect())

下一行dropTargets是一个视图列表,可以接受我的应用中的放置。 接下来,我遍历每个视图。

然后我使用getHitRect(r)返回视图的屏幕坐标。

然后我将coordiantes偏移以考虑通知栏或可能取代coordiantes的任何其他视图。

最后我看到x和y是否在给定矩形r的坐标内(x和y是event.rawX()和event.rawY())。

事实证明它比预期更简单并且效果很好。

答案 3 :(得分:2)