I have a ListView inside of a ViewFlipper which I am flipping when the user swipes across the screen. Clicking on a ListView will open the browser. Sometimes when I am swiping,
The way this is normally done is through the parent view's onInterceptTouchEvent method. onInterceptTouchEvent
has a chance to see any touch event before a view's children do. If onInterceptTouchEvent
returns true
the child view that was previously handling touch events receives an ACTION_CANCEL
and the events from that point forward are sent to the parent's onTouchEvent
method for the usual handling. It can also return false
and simply spy on events as they travel down the view hierarchy to their usual targets.
You want to do essentially this in onInterceptTouchEvent
on the parent view where you're detecting the flings:
ACTION_DOWN
, record the location of the touch. Return false
.ACTION_MOVE
, check the delta between initial touch down position and current position. If it's past a threshold value, (the framework uses ViewConfiguration#getScaledTouchSlop() or other appropriate values from ViewConfiguration
for things like this,) return true
.onTouchEvent
.Once you intercept, the ListView
will cancel its touch handling and you won't get unwanted tap events on your list items. ListView
is also set up to disallow its parent from intercepting events once the user has started vertically scrolling the list, which means you won't get mistaken horizontal flings if the user sloppily flings the list vertically.
This is how things like the stock Android Launcher or News and Weather do side to side paging of scrolling/tappable content.
Have you tried using SimpleOnGestureListener.onSingleTapConfirmed(MotionEvent) for the on touch event ("click")? This will only be called after the detector is confident that the user's first tap is really a tap and not a double tap (or hopefully a fling).
class MyGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
// Code...
}
}