Android onTouch с помощью onClick и onLongClick - PullRequest
8 голосов
/ 12 сентября 2011

У меня есть пользовательский вид, который действует как кнопка.Я хочу изменить фон, когда пользователь нажимает его, вернуть фон к исходному, когда пользователь перемещает палец наружу или отпустить его, и я также хочу обрабатывать события onClick / onLongClick.Проблема в том, что onTouch требует, чтобы я возвратил true для ACTION_DOWN, иначе он не отправит мне событие ACTION_UP.Но если я верну true, прослушиватель onClick не будет работать.

Я подумал, что решил эту проблему, вернув false в onTouch и зарегистрировав onClick - это каким-то образом сработало, но было своего рода против документов.Я только что получил сообщение от пользователя, в котором говорится, что он не может долго нажимать на кнопку, поэтому мне интересно, что здесь не так.

Часть текущего кода:

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);

Как мне заставить их работать вместе правильно?

Заранее спасибо

1 Ответ

13 голосов
/ 26 ноября 2011

onClick & onLongClick фактически отправлено с View.onTouchEvent.

если вы переопределите View.onTouchEvent или зададите какой-то конкретный View.OnTouchListener через setOnTouchListener, Вы должны заботиться об этом.

поэтому ваш код должен выглядеть примерно так:

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;
}
...