Android onTouch with onClick and onLongClick

12,185

onClick & onLongClick is actually dispatched from View.onTouchEvent.

if you override View.onTouchEvent or set some specific View.OnTouchListener via setOnTouchListener, you must care for that.

so your code should be something like:

public boolean onTouch(View v, MotionEvent evt)
{
  // to dispatch click / long click event,
  // you must pass the event to it's default callback View.onTouchEvent
  boolean defaultResult = v.onTouchEvent(evt);

  switch (evt.getAction())
  {
    case MotionEvent.ACTION_DOWN:
    {
      setSelection(true); // just changing the background
      break;
    }
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_OUTSIDE:
    {
      setSelection(false); // just changing the background
      break;
    }
    default:
      return defaultResult;
  }

  // if you reach here, you have consumed the event
  return true;
}
Share:
12,185

Related videos on Youtube

Sebastian Nowak
Author by

Sebastian Nowak

Updated on June 04, 2022

Comments

  • Sebastian Nowak
    Sebastian Nowak almost 2 years

    I've got a custom view which acts like a button. I want to change the background when user press it, revert the background to original when user moves the finger outside or release it and I also want to handle onClick/onLongClick events. The problem is that onTouch requires me to return true for ACTION_DOWN or it won't send me the ACTION_UP event. But if I return true the onClick listener won't work.

    I thought I solved it by returning false in onTouch and registering onClick - it somehow worked, but was kinda against the docs. I've just received a message from an user telling me that he's not able to long-click on the button, so I'm wondering what's wrong here.

    Part of the current code:

    public boolean onTouch(View v, MotionEvent evt)
    {
      switch (evt.getAction())
      {
        case MotionEvent.ACTION_DOWN:
        {
          setSelection(true); // it just change the background
          break;
        }
    
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_OUTSIDE:
        {
          setSelection(false); // it just change the background
          break;
        }
      }
    
      return false;
    }
    
    public void onClick(View v)
    {
      // some other code here
    }
    
    public boolean onLongClick(View view)
      {
        // just showing a Toast here
        return false;
      }
    
    
    // somewhere else in code
    setOnTouchListener(this);
    setOnClickListener(this);
    setOnLongClickListener(this);
    

    How do I make them work together correctly?

    Thanks in advance

  • 9re
    9re almost 5 years
    @ranasaha Handling this event is complecated. Check all your code which relates to touch event. Just reporting Doesent work will not help your problem. Re-consider why it doesn't work before posting poor reports on the incident to me.