我在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; }
通常通过父视图的onInterceptTouchEvent方法来完成此操作。onInterceptTouchEvent有机会在视图的子项之前看到任何触摸事件。如果onInterceptTouchEvent返回true,则以前处理触摸事件的子视图会收到一个ACTION_CANCEL,然后从该点开始的事件将发送到父级的onTouchEvent方法中进行常规处理。当false事件沿视图层次结构到达其通常的目标时,它也可以返回并监视事件。
onInterceptTouchEvent
true
ACTION_CANCEL
onTouchEvent
false
您基本上想onInterceptTouchEvent在检测到猛击的父视图中执行此操作:
ACTION_DOWN
ACTION_MOVE
ViewConfiguration#getScaledTouchSlop()
ViewConfiguration
拦截后,ListView将会取消其触摸处理,并且您的列表项上也不会收到不需要的点击事件。ListView还设置为,一旦用户开始垂直滚动列表,就禁止其父项拦截事件,这意味着如果用户草率地垂直拖动列表,您就不会出现错误的水平翻转。
ListView
这就是股票Android Launcher或News and Weather这样的事情如何进行滚动/可敲击内容的并排翻页。