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
Android OnTouch MotionEvent Actions
提问by ????????
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
事件被调用。
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_MOVE
is called along with ACTION_DOWN
because 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 onTouch
MotionEvent
actions. So here is a snippet copied from the documentation:
根据问题的标题,我来到这里是为了寻找操作的快速参考onTouch
MotionEvent
。所以这是从文档中复制的片段:
@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. (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; } });
- Returning
true
means that future events will still be processed. So if you returnedfalse
forACTION_DOWN
then 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; } });
- 返回
true
意味着未来的事件仍将被处理。因此,如果您返回false
forACTION_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 毫秒或类似的时间 - 之后可以继续进行“拖动”操作。在此之前,它应该只是一个“点击”操作。