简体   繁体   English

Android OnTouch MotionEvent 动作

[英]Android OnTouch MotionEvent Actions

So I think I have a very simple issue but I can't seem to figure it out.所以我想我有一个非常简单的问题,但我似乎无法弄清楚。

I have an ImageView and I am using it's setOnTouchListener method ( OnTouch ).我有一个ImageView ,我正在使用它的setOnTouchListener方法( OnTouch )。

How can I differentiate between the ACTION_DOWN event and ACTION_MOVE event?如何区分ACTION_DOWN事件和ACTION_MOVE事件?

Even when I just click (touch) on the ImageView , ACTION_MOVE event gets called.即使我只是在ImageView上单击(触摸), ACTION_MOVE调用ACTION_MOVE事件。

My goal is to open something(do anything) when the user clicks on it and move it when user holds it and moves it.我的目标是当用户点击它时打开它(做任何事情)并在用户握住它并移动它时移动它。

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;
}

As others have said, ACTION_MOVE is called along with ACTION_DOWN because of the sensitivity of the device and the inherent unsensitivity of big fingers.正如其他人所说,由于设备的敏感性和大手指固有的不敏感性, ACTION_MOVEACTION_DOWN一起调用。 This is known as touch slop .这称为接触溢出 The results you want can be obtained by adjusting the thresholds for time and distance moved.您可以通过调整移动时间和距离的阈值来获得您想要的结果。 Alternatively, you could use a gesture detector .或者,您可以使用手势检测器

OnTouch MotionEvent Actions OnTouch MotionEvent 动作

Based on the title of the question, I came here looking for a quick reference for the onTouch MotionEvent actions.基于该问题的标题,我来这里是找了一个快速参考onTouch MotionEvent行动。 So here is a snippet copied from the documentation :所以这是从 文档中复制的片段:

@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);
    }
}

Notes:笔记:

  • The above code could be used in an activity or a subclassed view.上面的代码可以在活动或子类视图中使用。 If subclassing a view is not desired, then the same motion events can be tracked by adding an OnTouchListener to the view.如果不需要子类化视图,则可以通过向视图添加OnTouchListener来跟踪相同的运动事件。 (example also taken from the 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() getAction()getActionMasked()区别

  • Returning true means that future events will still be processed.返回true意味着仍将处理未来的事件。 So if you returned false for ACTION_DOWN then all other events (like move or up) would be ignored.因此,如果您为ACTION_DOWN返回false ,则所有其他事件(如移动或向上)都将被忽略。

Further reading进一步阅读

  • Using Touch Gestures : This is a series of official lessons in the documentation. 使用触摸手势:这是文档中的一系列官方课程。 It is an essential read for understanding how to correctly handle touch events and gestures.这是了解如何正确处理触摸事件和手势的必备读物。

What is happening is that View.OnTouchListener will send you ALL events.发生的事情是 View.OnTouchListener 将向您发送所有事件。 If you tap and move by only 1 pixel, it'll be registered as a ACTION_MOVE.如果您点击并仅移动 1 个像素,它将被注册为 ACTION_MOVE。

You will need to implement some logic to determine a 'hold' action - waiting 100ms or something similar - after which a 'drag' action can proceed.您将需要实现一些逻辑来确定“保持”操作 - 等待 100 毫秒或类似的时间 - 之后可以继续进行“拖动”操作。 Before that time, it should just be a 'click' action.在此之前,它应该只是一个“点击”操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM