I have a view that need to process onTouch gestures and onClick events. What is the proper way to achieve this?
I have an onTouchListener
and an onClickListener
set on the view. Whenever I do touch the view, first the onTouch
event is triggered and later the onClick
. However, from the onTouch
event handler I have to return either true
or false
. Returning true
means that the event is being consumed, so the android event system will not propagate the event any further.
Therefore, an onClick
event is never generated, atleast my onClick
listener is never triggered when I return true
in my onTouch
event handler. On the other hand, returning false
there is not an option, since this prevents the onTouch
listener from receiving any further events that are necessary in order to recognize a gesture. What's the usual way of solving this?
In you GestureDetector, you can call callOnClick() directly. Note the View.callOnClick API requires API level 15. Just have a try.
// Create a Gesturedetector
GestureDetector mGestureDetector = new GestureDetector(context, new MyGestureDetector());
// Add a OnTouchListener into view
m_myViewer.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
return mGestureDetector.onTouchEvent(event);
}
});
private class MyGestureDetector extends GestureDetector.SimpleOnGestureListener
{
public boolean onSingleTapUp(MotionEvent e) {
// ---Call it directly---
callOnClick();
return false;
}
public void onLongPress(MotionEvent e) {
}
public boolean onDoubleTap(MotionEvent e) {
return false;
}
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}
public void onShowPress(MotionEvent e) {
LogUtil.d(TAG, "onShowPress");
}
public boolean onDown(MotionEvent e) {
// Must return true to get matching events for this down event.
return true;
}
public boolean onScroll(MotionEvent e1, MotionEvent e2, final float distanceX, float distanceY) {
return super.onScroll(e1, e2, distanceX, distanceY);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// do something
return super.onFling(e1, e2, velocityX, velocityY);
}
}