Android MotionEvent:查看视图外是否发生了动作

时间:2012-06-23 19:03:30

标签: android motion-detection

我有一个按钮和OnTouchListener附加到它。如何查找运动(当用户按下按钮时)是在内部还是外部发生? event.getAction()和event.getActionMasked()都只返回0,1或2,分别是ActionDown,ActionUp,ActionMove。有一个常量的MotionEvent.ACTION_OUTSIDE,它是4,但即使我在按钮外拖动触摸,我也不会收到它 - 我仍然从这两种方法中获得2。有什么问题?

UPD:我找到了很好的解决方案 - 只需在ACTION_UP之后检查焦点状态。如果它没有聚焦,则意味着移动发生在视图之外。

5 个答案:

答案 0 :(得分:8)

该标志仅适用于Windows,而不适用于视图。当您将手指移离视图时,您将获得ACTION_MOVE,该事件将保留在其生成的视图中。如果您需要澄清,请查看SeekBar的源代码:即使您将手指从栏上移开,拇指仍会拖动!

要在Window级别使用FLAG_WATCH_OUTSIDE_TOUCH执行此操作,它可以正常工作。

答案 1 :(得分:6)

case MotionEvent.ACTION_CANCEL为我工作。

答案 2 :(得分:6)

MotionEvent.ACTION_OUTSIDE不适用于View。

一种解决方案是获取X和Y触摸位置并验证它是否在视图的边界内。可以这样做:

@Override
public boolean onTouchEvent(MotionEvent e) {
    if (e.getX()<0 || e.getY()<0 || e.getX()>getMeasuredWidth() || e.getY()>getMeasuredHeight())
        Log.i(TAG, "TOUCH OUTSIDE");
    else
        Log.i(TAG, "TOUCH INSIDE");

    return true;
}

答案 3 :(得分:4)

如果OnTouchListener上有Button,您只会收到Button内的动作事件。仅当动作事件超出MotionEvent.ACTION_OUTSIDE的范围时才会调用View,您应该将其视为ACTION_UP

答案 4 :(得分:0)

public static boolean touchWithinBounds(MotionEvent event, View view) {
    if (event == null || view == null || view.getWidth() == 0 || view.getHeight() == 0)
        return false;

    int[] viewLocation = new int[2];
    view.getLocationOnScreen(viewLocation);
    int viewMaxX = viewLocation[0] + view.getWidth() - 1;
    int viewMaxY = viewLocation[1] + view.getHeight() - 1;
    return (event.getRawX() <= viewMaxX && event.getRawX() >= viewLocation[0]
        && event.getRawY() <= viewMaxY && event.getRawY() >= viewLocation[1]);
}

当您从其他视图转发触摸事件时的解决方案