Ana*_*sia 70 android event-handling touch-event android-event
在我的应用程序中,我需要处理移动和单击事件.
单击是一个ACTION_DOWN操作的序列,几个ACTION_MOVE操作和一个ACTION_UP操作.理论上,如果您获得ACTION_DOWN事件然后获得ACTION_UP事件 - 这意味着用户刚刚单击了您的视图.
但实际上,这个序列在某些设备上不起作用.在我的三星Galaxy Gio上,只需单击我的视图:ACTION_DOWN,几次ACTION_MOVE,然后ACTION_UP即可获得此类序列.即我使用ACTION_MOVE动作代码获得了一些无法预料的OnTouchEvent激活.我从未(或几乎从不)获得序列ACTION_DOWN - > ACTION_UP.
我也不能使用OnClickListener,因为它没有给出点击的位置.那么如何检测点击事件并将其与移动区分开来呢?
Sti*_*oni 103
这是另一种非常简单的解决方案,不需要担心手指被移动.如果您只是根据移动的距离进行点击,那么如何区分点击和长按.
您可以将更多的智能放入其中并包括移动的距离,但是当用户可以在200毫秒内移动的距离构成移动而不是单击时,我还没遇到过实例.
setOnTouchListener(new OnTouchListener() {
private static final int MAX_CLICK_DURATION = 200;
private long startClickTime;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
startClickTime = Calendar.getInstance().getTimeInMillis();
break;
}
case MotionEvent.ACTION_UP: {
long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime;
if(clickDuration < MAX_CLICK_DURATION) {
//click event has occurred
}
}
}
return true;
}
});
Run Code Online (Sandbox Code Playgroud)
Jon*_*nik 49
考虑到以下因素,我得到了最好的结果:
ACTION_DOWN
和ACTION_UP
事件之间的距离.我想指定密度不依赖像素而不是像素的最大允许距离,以更好地支持不同的屏幕.例如,15 DP.例:
/**
* Max allowed duration for a "click", in milliseconds.
*/
private static final int MAX_CLICK_DURATION = 1000;
/**
* Max allowed distance to move during a "click", in DP.
*/
private static final int MAX_CLICK_DISTANCE = 15;
private long pressStartTime;
private float pressedX;
private float pressedY;
@Override
public boolean onTouchEvent(MotionEvent e) {
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN: {
pressStartTime = System.currentTimeMillis();
pressedX = e.getX();
pressedY = e.getY();
break;
}
case MotionEvent.ACTION_UP: {
long pressDuration = System.currentTimeMillis() - pressStartTime;
if (pressDuration < MAX_CLICK_DURATION && distance(pressedX, pressedY, e.getX(), e.getY()) < MAX_CLICK_DISTANCE) {
// Click event has occurred
}
}
}
}
private static float distance(float x1, float y1, float x2, float y2) {
float dx = x1 - x2;
float dy = y1 - y2;
float distanceInPx = (float) Math.sqrt(dx * dx + dy * dy);
return pxToDp(distanceInPx);
}
private static float pxToDp(float px) {
return px / getResources().getDisplayMetrics().density;
}
Run Code Online (Sandbox Code Playgroud)
这里的想法与Gem的解决方案相同,但存在以下差异:
更新(2015年):还可以查看Gabriel的微调版本.
Gab*_*iel 27
以Jonik为首,我制作了一个稍微精细的调整版本,如果您移动手指然后在放手之前返回现场,则不会注册为单击:
所以这是我的解决方案:
/**
* Max allowed duration for a "click", in milliseconds.
*/
private static final int MAX_CLICK_DURATION = 1000;
/**
* Max allowed distance to move during a "click", in DP.
*/
private static final int MAX_CLICK_DISTANCE = 15;
private long pressStartTime;
private float pressedX;
private float pressedY;
private boolean stayedWithinClickDistance;
@Override
public boolean onTouchEvent(MotionEvent e) {
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN: {
pressStartTime = System.currentTimeMillis();
pressedX = e.getX();
pressedY = e.getY();
stayedWithinClickDistance = true;
break;
}
case MotionEvent.ACTION_MOVE: {
if (stayedWithinClickDistance && distance(pressedX, pressedY, e.getX(), e.getY()) > MAX_CLICK_DISTANCE) {
stayedWithinClickDistance = false;
}
break;
}
case MotionEvent.ACTION_UP: {
long pressDuration = System.currentTimeMillis() - pressStartTime;
if (pressDuration < MAX_CLICK_DURATION && stayedWithinClickDistance) {
// Click event has occurred
}
}
}
}
private static float distance(float x1, float y1, float x2, float y2) {
float dx = x1 - x2;
float dy = y1 - y2;
float distanceInPx = (float) Math.sqrt(dx * dx + dy * dy);
return pxToDp(distanceInPx);
}
private static float pxToDp(float px) {
return px / getResources().getDisplayMetrics().density;
}
Run Code Online (Sandbox Code Playgroud)
Gil*_* SH 17
使用探测器,它可以工作,并且在拖动的情况下不会升起
领域:
private GestureDetector mTapDetector;
Run Code Online (Sandbox Code Playgroud)
初始化:
mTapDetector = new GestureDetector(context,new GestureTap());
Run Code Online (Sandbox Code Playgroud)
内班:
class GestureTap extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDoubleTap(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// TODO: handle tap here
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
onTouch:
@Override
public boolean onTouch(View v, MotionEvent event) {
mTapDetector.onTouchEvent(event);
return true;
}
Run Code Online (Sandbox Code Playgroud)
请享用 :)
要获得最佳的点击事件识别我们必须考虑两件事:
实际上我结合了Stimsoni和Neethirajan给出的逻辑
所以这是我的解决方案:
view.setOnTouchListener(new OnTouchListener() {
private final int MAX_CLICK_DURATION = 400;
private final int MAX_CLICK_DISTANCE = 5;
private long startClickTime;
private float x1;
private float y1;
private float x2;
private float y2;
private float dx;
private float dy;
@Override
public boolean onTouch(View view, MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
{
startClickTime = Calendar.getInstance().getTimeInMillis();
x1 = event.getX();
y1 = event.getY();
break;
}
case MotionEvent.ACTION_UP:
{
long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime;
x2 = event.getX();
y2 = event.getY();
dx = x2-x1;
dy = y2-y1;
if(clickDuration < MAX_CLICK_DURATION && dx < MAX_CLICK_DISTANCE && dy < MAX_CLICK_DISTANCE)
Log.v("","On Item Clicked:: ");
}
}
return false;
}
});
Run Code Online (Sandbox Code Playgroud)
使用 Gil SH 答案,我通过实施onSingleTapUp()
而不是onSingleTapConfirmed()
. 它要快得多,如果拖动/移动也不会单击视图。
手势点击:
public class GestureTap extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent e) {
button.performClick();
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
final GestureDetector gestureDetector = new GestureDetector(getApplicationContext(), new GestureTap());
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
gestureDetector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
return true;
case MotionEvent.ACTION_UP:
return true;
case MotionEvent.ACTION_MOVE:
return true;
}
return false;
}
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
41378 次 |
最近记录: |