Intereting Posts

Невозможно одновременно обрабатывать события click и touch

Я пытаюсь обработать события касания и нажать события на кнопке. Я делаю следующее:

button.setOnClickListener(clickListener); button.setOnTouchListener(touchListener); 

Когда регистрируется какой-либо один слушатель, все работает нормально, но когда я пытаюсь использовать их, срабатывают только события касания. Любое обходное решение? Что я делаю не так?

Solutions Collecting From Web of "Невозможно одновременно обрабатывать события click и touch"

Существует тонкое, но очень важное различие между ClickListener и TouchListener . TouchListener выполняется до того, как представление может ответить на событие. ClickListener получит свое событие только после того, как представление обработало его.

Поэтому, когда вы касаетесь экрана, TouchListener выполняется первым, и когда вы возвращаете true для своего события, ClickListener никогда не получит его. Но если вы нажмете трекбол своего устройства, ClickListener должен быть запущен, потому что TouchListener не ответит на него.

Это немного сложно.

Если вы установите onTouchListener вам нужно вернуть true в ACTION_DOWN , чтобы сообщить системе, что я использовал это событие, и он не будет просачиваться к другим слушателям.

Но тогда OnClickListener не будет запущен.

Так что вы можете подумать, я просто сделаю свое дело и вернусь к false чтобы получить клики тоже. Если вы это сделаете, это будет работать, но вы не будете подписаны на другие предстоящие события касания ( ACTION_MOVE , ACTION_UP ). Поэтому единственным вариантом является возврат true там, но тогда вы не будете получать никаких событий кликов, как мы сказали ранее.

Поэтому вам нужно выполнить щелчок вручную в ACTION_UP с помощью view.performClick()

Это сработает.

Спасибо @urSus за отличный ответ
Но в этом случае каждое нажатие будет выполнять щелчок, даже ACTION_MOVE
Предполагая, что вы хотите разделить событие move событие click вы можете использовать небольшой трюк
Определите boolean поле и используйте вот так:

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

Полагаю, вы вернулись в свой OnTouchListener ? Это будет потреблять событие, поэтому оно не будет отправлено для дальнейшей обработки.

На стороне примечания – в чем смысл иметь и щелчок и прикосновение слушателя?

Вы должны вернуть false в свой OnTouchListener тогда будет обработан ваш OnClickListener .

 button.setOnTouchListener(this); 

Внедрите интерфейс и код здесь:

 @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (view.getId()) { case R.id.send: switch(motionEvent.getAction()){ case MotionEvent.ACTION_DOWN: //when the user has pressed the button //do the needful here break; case MotionEvent.ACTION_UP: //when the user releases the button //do the needful here break; } break; } return false; }