Can't handle both click and touch events simultaneously
Its a little tricky.
If you set onTouchListener
you need to return true
in ACTION_DOWN
, to tell the system that I have consumed the event and it won't trickle down to other listeners.
But then OnClickListener
won't be fired.
So you might think, I will just do my thing there and return false
so I can receive clicks too.
If you do so, it will work, but you won't be subscribed to other upcoming touch events (ACTION_MOVE
, ACTION_UP
)
Therefore, the only option is to return true
there, but then you won't receive any click events as we said previously.
So you need to perform the click manually in the ACTION_UP
with view.performClick()
This will work.
There is a subtle, yet very important difference between the ClickListener
and the TouchListener
. The TouchListener
is executed before the view can respond to the event. The ClickListener
will receive its event only after the view has handled it.
So when you touch your screen, the TouchListener
is executed first and when you return true
for your event, the ClickListener
will never get it. But if you press the trackball of your device, the ClickListener
should be fired because the TouchListener
will not respond to it.
Thanks to @urSus for great answer
But in that case every touch will perform click, Even ACTION_MOVE
Assuming you want to separate move
event and click
event you can use a little trick
define a boolean
field and use like this:
@Override
public boolean onTouch(View view, MotionEvent motionEvent)
{
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
shouldClick = true;
.
.
break;
case MotionEvent.ACTION_UP:
if (shouldClick)
view.performClick();
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
//Do your stuff
shouldClick = false;
break;
}
rootLayout.invalidate();
return true;
}