Intereting Posts

OnTouchEvent не работает над дочерними представлениями

У меня есть линейная компоновка, на которой есть Button и TextView. Я написал OnTouchEvent для этой деятельности. Код работает нормально, если я касаюсь экрана, но если я касаюсь кнопки, код не работает. Какое возможное решение для этого?

public boolean onTouchEvent(MotionEvent event) { int eventaction=event.getAction(); switch(eventaction) { case MotionEvent.ACTION_MOVE: reg.setText("hey"); break; } return true; } 

Solutions Collecting From Web of "OnTouchEvent не работает над дочерними представлениями"

Проблема заключается в том, как работает Android для сенсорных событий. Каждое событие касания следует шаблону (упрощенный пример):

  1. Activity.dispatchTouchEvent ()
  2. ViewGroup.dispatchTouchEvent ()
  3. View.dispatchTouchEvent ()
  4. View.onTouchEvent ()
  5. ViewGroup.onTouchEvent ()
  6. Activity.onTouchEvent ()

Но события следуют за цепочкой до тех пор, пока они не будут потреблены (что означает, что кто-то возвращает true из onTouchEvent() или слушателя). В случае, когда вы просто касаетесь где-то на экране, никто не заинтересован в событии, поэтому он полностью переносится на ваш код. Однако в случае кнопки (или другого кликабельного View ) он потребляет событие касания, потому что оно его интересует, поэтому поток останавливается в строке 4.

Если вы хотите отслеживать все касания, которые входят в вашу активность, вам необходимо переопределить dispatchTouchEvent() так как тот, который всегда onTouchEvent() первым, onTouchEvent() для Activity получает последний вызов, и только если никто не зафиксировал событие. Будьте осторожны, чтобы не использовать здесь события, или детские представления никогда не получат их, и ваши кнопки не будут доступны.

 public boolean dispatchTouchEvent(MotionEvent event) { int eventaction=event.getAction(); switch(eventaction) { case MotionEvent.ACTION_MOVE: reg.setText("hey"); break; default: break; } return super.dispatchTouchEvent(event); } 

Другим вариантом было бы поместить ваш код обработки касания в пользовательскую ViewGroup (например, LinearLayout ) и использовать его onInterceptTouchEvent() чтобы позволить родительскому представлению украсть и обработать события касания, когда это необходимо. Будьте осторожны, так как это взаимодействие – это тот, который нельзя отменить, пока не начнется новое событие касания (как только вы украдете одно событие, вы украдете их все).

НТН

Позвольте мне добавить еще один комментарий к этому замечательному сообщению от @Devunwired.

Если вы также установили onTouchListener в своем представлении, тогда его метод onTouch () будет вызван ПОСЛЕ методов отправки, но ПЕРЕД любым методом onTouchEvent (), т.е. между 3 и 4 в ответ на ответ Devunwired.

Попробуйте установить атрибут descendantFocusability вашего макета для блоковDescendants

Activity::onTouchEvent будет вызываться только тогда, когда не из видов в Activity WIndow потребляет / обрабатывает событие. Если вы коснетесь Button , Button будет потреблять события, поэтому Activity не сможет ее обработать.

Ознакомьтесь со следующими статьями для получения дополнительной информации о конвейере обработки событий Android Touch Event.

http://pierrchen.blogspot.jp/2014/03/pipeline-of-android-touch-event-handling.html

Вы также можете попробовать onUserInteraction() :

 @Override public void onUserInteraction(){ //your code here super.onUserInteraction(); } 

Хорошо работает для меня!