【问题标题】:Android MotionEvent: find out if motion happened outside the viewAndroid MotionEvent:找出运动是否发生在视图之外
【发布时间】:2012-06-25 16:43:02
【问题描述】:

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

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

【问题讨论】:

    标签: android motion-detection


    【解决方案1】:

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

    要在窗口级别执行此操作,请使用FLAG_WATCH_OUTSIDE_TOUCH,它工作得很好。

    【讨论】:

      【解决方案2】:

      如果OnTouchListenerButton 上,您将只能从Button 中接收运动事件。 MotionEvent.ACTION_OUTSIDE 只会在运动事件第一次超出 View 的范围时被调用,您应该像对待 ACTION_UP 一样对待它。

      【讨论】:

        【解决方案3】:

        case MotionEvent.ACTION_CANCEL 为我工作。

        【讨论】:

          【解决方案4】:

          MotionEvent.ACTION_OUTSIDE 不适用于 View。

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

          @Override
          public boolean onTouchEvent(MotionEvent e) {
              if (isInside())
                  Log.i(TAG, "TOUCH INSIDE");
              else
                  Log.i(TAG, "TOUCH OUTSIDE");
              return true;
          }
          
          private boolean isInside(View v, MotionEvent e) {
              return !(e.getX() < 0 || e.getY() < 0
                      || e.getX() > v.getMeasuredWidth()
                      || e.getY() > v.getMeasuredHeight());
          }
          

          【讨论】:

            【解决方案5】:
            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]);
            }
            

            从不同视图转发触摸事件时的解决方案

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-03-10
              • 2022-06-19
              • 1970-01-01
              • 2020-06-30
              • 1970-01-01
              • 2011-10-06
              • 2021-12-29
              相关资源
              最近更新 更多