我在ViewFlipper中有一个ListView,当用户在屏幕上滑动时我正在翻转它。单击ListView将打开浏览器。有时当我滑动时,它会在ListView上被检测为触摸并打开浏览器。这可能很烦人。我怎样才能防止这种情况发生?
class MyGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
// right to left swipe
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
viewFlipper.setInAnimation(slideLeftIn);
viewFlipper.setOutAnimation(slideLeftOut);
viewFlipper.showNext();
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
viewFlipper.setInAnimation(slideRightIn);
viewFlipper.setOutAnimation(slideRightOut);
viewFlipper.showPrevious();
}
if (viewFlipper.getDisplayedChild() == 0) {
// TODO: light up left
flipperPosition = 0;
} else if (viewFlipper.getDisplayedChild() == 1) {
// TODO: light up middle
flipperPosition = 1;
} else if (viewFlipper.getDisplayedChild() == 2) {
// TODO: light up right
flipperPosition = 2;
}
} catch (Exception e) {
System.out.println(e);
}
return false;
}
}
protected MotionEvent downStart = null;
public boolean onInterceptTouchEvent(MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
// keep track of the starting down-event
downStart = MotionEvent.obtain(event);
break;
case MotionEvent.ACTION_MOVE:
// if moved horizontally more than slop*2, capture the event for ourselves
float deltaX = event.getX() - downStart.getX();
if(Math.abs(deltaX) > ViewConfiguration.getTouchSlop() * 2)
return true;
break;
}
// otherwise let the event slip through to children
return false;
}
答案 0 :(得分:13)
通常通过父视图的onInterceptTouchEvent
方法完成此操作。 onInterceptTouchEvent
有机会在观看孩子之前看到任何触摸事件。如果onInterceptTouchEvent
返回true
,之前处理触摸事件的子视图会收到ACTION_CANCEL
,并且从该点开始的事件将被发送到父级的onTouchEvent
方法以进行常规处理。它还可以返回false
并在事件沿着视图层次结构向下移动到通常的目标时监视事件。
您希望在父视图中的onInterceptTouchEvent
中执行此操作,您要检测到flings:
ACTION_DOWN
上,记录触摸的位置。返回false
。ACTION_MOVE
上,检查初始触地位置和当前位置之间的差值。如果超过阈值(框架使用ViewConfiguration#getScaledTouchSlop()
或ViewConfiguration
中的其他适当值来执行此类操作,则返回true
。onTouchEvent
拦截后,ListView
将取消其触摸处理,您不会在列表项上获得不需要的点击事件。 ListView
也设置为禁止其父级在用户开始垂直滚动列表时拦截事件,这意味着如果用户在垂直方向上拖动列表,则不会出现错误的水平偏移。
这就是Android启动器或新闻和天气这样的东西如何对滚动/可点击内容进行左右分页。
答案 1 :(得分:1)
您是否尝试过使用SimpleOnGestureListener.onSingleTapConfirmed(MotionEvent)进行触摸事件(“点击”)?这只会在探测器确信用户的第一次点击确实是点击而不是双击(或希望是一次性)后才会被调用。
class MyGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
// Code...
}
}