【问题标题】:Android OnTouch MotionEvent ActionsAndroid OnTouch MotionEvent 动作
【发布时间】:2015-09-11 14:51:51
【问题描述】:

所以我认为我有一个非常简单的问题,但我似乎无法弄清楚。

我有一个 ImageView,我正在使用它的 setOnTouchListener 方法 (OnTouch)。

如何区分ACTION_DOWN 事件和ACTION_MOVE 事件?

即使我只是单击(触摸)ImageViewACTION_MOVE 事件也会被调用。

我的目标是当用户点击它时打开某物(做任何事情),当用户握住它并移动它时移动它。

private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;

@Override
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            initialX = params.x;
            initialY = params.y;
            initialTouchX = event.getRawX();
            initialTouchY = event.getRawY();
            return true;
       case MotionEvent.ACTION_UP:
           return true;
       case MotionEvent.ACTION_MOVE:
           params.x = initialX + (int) (event.getRawX() - initialTouchX);
           params.y = initialY + (int) (event.getRawY() - initialTouchY);
           mWindowManager.updateViewLayout(mImgFloatingView, params);

           // Log.d("Params", "X: " + params.x + ".  Y: " + params.y + ".");

          if(params.x == initialX && params.y == initialY) {
              Toast.makeText(getBaseContext(), "Test", Toast.LENGTH_SHORT).show();
          }

          return true;
      }
      return false;
}

【问题讨论】:

  • ACTION_DOWN 在您第一次将手指放在屏幕上时被调用。然后,如果您将手指放在屏幕上并开始移动它,则会调用 ACTION_MOVE
  • 我明白这一点,但我的问题是当我点击ImageView 时,首先调用 ACTION_DOWN,然后调用 ACTION_MOVE。即使我只是点击(单击)而不是移动,也会发生这种情况。这是为什么呢?

标签: java android android-studio onclicklistener ontouchlistener


【解决方案1】:

正如其他人所说,ACTION_MOVEACTION_DOWN 一起被调用是因为设备的敏感性和大手指固有的不敏感性。这被称为touch slop。您可以通过调整移动时间和距离的阈值来获得您想要的结果。或者,您可以使用gesture detector

OnTouch MotionEvent 动作

根据问题的标题,我来到这里寻找onTouch MotionEvent 操作的快速参考。所以这里是从documentation复制的一个sn-p:

@Override
public boolean onTouchEvent(MotionEvent event){

    int action = event.getActionMasked();

    switch(action) {
        case (MotionEvent.ACTION_DOWN) :
            Log.d(DEBUG_TAG,"Action was DOWN");
            return true;
        case (MotionEvent.ACTION_MOVE) :
            Log.d(DEBUG_TAG,"Action was MOVE");
            return true;
        case (MotionEvent.ACTION_UP) :
            Log.d(DEBUG_TAG,"Action was UP");
            return true;
        case (MotionEvent.ACTION_CANCEL) :
            Log.d(DEBUG_TAG,"Action was CANCEL");
            return true;
        case (MotionEvent.ACTION_OUTSIDE) :
            Log.d(DEBUG_TAG,"Movement occurred outside bounds " +
                    "of current screen element");
            return true;
        default :
            return super.onTouchEvent(event);
    }
}

注意事项:

  • 以上代码可用于活动或子类视图。如果不需要子类化视图,则可以通过向视图添加OnTouchListener 来跟踪相同的运动事件。 (示例也取自documentation

      View myView = findViewById(R.id.my_view);
      myView.setOnTouchListener(new OnTouchListener() {
          public boolean onTouch(View v, MotionEvent event) {
              // ... Respond to touch events
              return true;
          }
      });
    
  • Difference between getAction() and getActionMasked()

  • 返回true 表示未来的事件仍将被处理。因此,如果您为 ACTION_DOWN 返回了 false,那么所有其他事件(如移动或向上)都将被忽略。

进一步阅读

  • Using Touch Gestures:这是官方文档中的系列教程。这是了解如何正确处理触摸事件和手势的必备读物。

【讨论】:

    【解决方案2】:

    正在发生的事情是 View.OnTouchListener 将向您发送所有事件。如果您点击并仅移动 1 个像素,它将被注册为 ACTION_MOVE。

    您将需要实现一些逻辑来确定“保持”动作 - 等待 100 毫秒或类似的时间 - 之后才能进行“拖动”动作。在此之前,它应该只是一个“点击”动作。

    【讨论】:

      猜你喜欢
      • 2015-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-01
      相关资源
      最近更新 更多