Подтвердить что ты не робот

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;

  }
4b9b3361

Ответ 1

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

  • Activity.dispatchTouchEvent()
  • ViewGroup.dispatchTouchEvent()
  • View.dispatchTouchEvent()
  • View.onTouchEvent()
  • ViewGroup.onTouchEvent()
  • Activity.onTouchEvent()

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

Если вы хотите отслеживать все касания, которые входят в вашу активность, вам необходимо переопределить dispatchTouchEvent(), так как то, что всегда вызывается первым, 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(), чтобы позволить родительскому представлению украсть и обработать события касания, когда это необходимо. Однако будьте осторожны, так как это взаимодействие не может быть отменено до тех пор, пока не начнется новое событие касания (как только вы украдете одно событие, вы украдите все).

НТН

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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

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

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