java Android OnTouch MotionEvent 动作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32526332/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 20:19:32  来源:igfitidea点击:

Android OnTouch MotionEvent Actions

javaandroidandroid-studioonclicklistenerontouchlistener

提问by ????????

So I think I have a very simple issue but I can't seem to figure it out.

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

I have an ImageViewand I am using it's setOnTouchListenermethod (OnTouch).

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

How can I differentiate between the ACTION_DOWNevent and ACTION_MOVEevent?

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

Even when I just click (touch) on the ImageView, ACTION_MOVEevent gets called.

甚至当我只需要点击(触摸)ImageViewACTION_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;
}

回答by Suragch

As others have said, ACTION_MOVEis called along with ACTION_DOWNbecause of the sensitivity of the device and the inherent unsensitivity of big fingers. 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.

正如其他人所说,由于设备的敏感性和大手指固有的不敏感性而ACTION_MOVE被称为ACTION_DOWN。这被称为接触溢出。可以通过调整移动时间和距离的阈值来获得您想要的结果。或者,您可以使用手势检测器

OnTouch MotionEvent Actions

OnTouch MotionEvent 动作

Based on the title of the question, I came here looking for a quick reference for the onTouchMotionEventactions. So here is a snippet copied from the documentation:

根据问题的标题,我来到这里是为了寻找操作的快速参考onTouchMotionEvent。所以这是从文档中复制的片段:

@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 OnTouchListenerto the view. (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()

  • Returning truemeans that future events will still be processed. So if you returned falsefor ACTION_DOWNthen all other events (like move or up) would be ignored.
  • 上面的代码可以用在活动或子类视图中。如果不需要对视图进行子类化,则可以通过向OnTouchListener视图添加 来跟踪相同的运动事件。 (示例也取自文档

    View myView = findViewById(R.id.my_view);
    myView.setOnTouchListener(new OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            // ... Respond to touch events
            return true;
        }
    });
    
  • getAction()和之间的区别getActionMasked()

  • 返回true意味着未来的事件仍将被处理。因此,如果您返回falseforACTION_DOWN那么所有其他事件(如移动或向上)将被忽略。

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.
  • 使用触摸手势:这是文档中的一系列官方课程。这是了解如何正确处理触摸事件和手势的必备读物。

回答by zmarkan

What is happening is that View.OnTouchListener will send you ALL events. If you tap and move by only 1 pixel, it'll be registered as a ACTION_MOVE.

发生的事情是 View.OnTouchListener 将向您发送所有事件。如果您点击并仅移动 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. Before that time, it should just be a 'click' action.

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