Ниже приведен пример прохождения события после нажатия на представление.
Во -первых, проанализируйте метод DispatchTouchEvent () в представлении, который является первым методом для выполнения, нажав на представление.
Public Boolean DispatchTouchEvent (Event MotionEvent) {if (montouchListener! = null && (mViewFlags & enabled_mask) == enabled && montouchlistener.ontouch (this, event)) {return true; } return ontouchevent (event);}Примечание. Он содержит две функции обратного вызова ontouch () и ontouchevent (); Если элемент управления связан с OnTouchListener и включен элемент управления, затем выполните метод ontouch (). Если метод возвращает True, это означает, что событие Touch было поглощено прослушивателем OnTouchListener и не будет распределена вниз; Но если ложный возврат, это означает, что он не был потреблен, и продолжает распределяться вниз по ontouchevent () управления для обработки.
Затем проанализируйте метод ontouchevent () и выполните дальнейшую обработку событий.
if (((viewflags & clickable) == clickable || (viewflags & long_clickable) == long_clickable)) {switch (event.getAction ()) {case motionEvent.action_up: ..... recomerclick (); // отвечать на Click Event Break; case motionEvent.action_down: .... Break; case motionEvent.action_cancel: .... Break; case motionevent.action_move: ..... break; } вернуть true; } вернуть false;Если элемент управления кликабельно или Long_Clickable, он может ответить на соответствующее событие и вернуть True после того, как ответ будет завершен для продолжения ответа. Например, нажав на событие, сначала ответьте на action_down, затем разбивайте и верните True, затем поднимите руку, затем раздайте его от DispatchTouchEvent (), а затем ответьте на action_up, и выполнить Comertclick () ответит на событие Click.
Ответьте на Click Events
public boolean exectionclick () {sendaccessibilityevent (accepbortibilityevent.type_view_clicked); if (monclicklistener! = null) {playsoundeffect (soundeffectconstants.click); monclicklistener.onclick (это); вернуть истину; } вернуть false;}Выполнить monclicklistener.onclick (это); то есть функция OnClick (), которая связывает слушателя.
Ключевые моменты:
Как использовать разницу между Ontouch и OntouchEvent?
отвечать:
Когда элемент управления представлением получает сенсорное событие, если элемент управления связан с прослушивателем ontouchlistener, а элемент управления включен, затем выполните метод ontouch (). Если это правда, событие Touch было потреблено и больше не будет передано; Если false возвращается, то продолжайте вызовать событие ontouchevent ().
После того, как событие Android Touch будет передано в DecerView (Framelayout) в верхней части деятельности, оно будет передано слой по слоям через группу просмотра к дереву просмотра и, наконец, передает событие фактическому полученному представлению. Вот несколько важных методов.
DispatchTouchEvent
Когда событие будет передано в группу просмотров, будет вызван DispatchTouchEvent. Код был удален
Public Boolean DispatchTouchEvent (MotionEvent EV) {Boolean Randled = false; if (OnfilterTouchEventForSecurity (ev)) {final int action = ev.getAction (); final int actionMasked = action & motionEvent.action_mask; // Внимание 1: Очистить некоторые состояния при нажатии if (actionmashed == motionEvent.action_down) {cancelandCleartouchTargets (ev); // Обратите внимание на этот метод RESetTouchState (); } // Внимание 2: Проверьте, необходимо ли перехватить окончательный логический перехват; // Если вы только что нажали или имеете дочернее представление, чтобы обработать его if (actionmashed == motionevent.action_down || mfirsttouchtarget! = Null) {final boolean dislowintercept = (mgroupflags & flag_disallow_intercept)! = 0; if (! dislowintercept) {rececepted = onInterceptTouchEvent (ev); Ev.SetAction (действие); // Восстановите действие в случае, если оно было изменено} else {rececepted = false; }} else {// Это не начало последовательности действий, и нет никаких подведений, чтобы справиться с ним. Перехватить напрямую = true; } // Событие не отменено и не перехвачено текущей группой просмотра. Перейдите, чтобы посмотреть, есть ли подвеса, взятый в случае, если (! Отменено &&! Перехватить) {// Если это начало серии действий или появился новый указатель, нам нужно найти подпрограмму, который может обрабатывать этот указатель if (actionmashed == motionevent.action_down || (split && actionshaked = motionevent.action_pointer_pownter_pownt. MotionEvent.action_hover_move) {final int actionIndex = ev.getActionIndex (); // всегда 0 для вниз // вышеуказанное ограничение точки сенсорной точки 32 заключается в том, что он вызывает окончательный int idbitstoassign = split? 1 << ev.getPointerId (actionIndex): touchTarget.all_pointer_ids; final int Childrencount = mChildRencount; if (newtouchtarget == null && childrencount! = 0) {final float x = ev.getx (actionIndex); final float y = ev.gety (actionIndex); // Сортируйте все детские представления текущей группы View Group и поместите их в верхний слой, чтобы начать. Final ArrayList <siew> предварительный заказ = buildorderedChildlist (); final Boolean Customorder = предварительно зарегистрированный список == null && ischildrendrawingorderenabled (); Окончательный вид [] дети = mChildren; для (int i = childrencount-1; i> = 0; i--) {final int childindex = customorder? getChildDrawingRoder (приседание детей, i): i; Окончательный просмотр child = (предварительный заказ == null)? Дети [Childindex]: предварительный заказ. Get (ChildIndex); // canViewReceivePointerEvents Видимое представление может принять события // istransformedTouchPointInview Рассчитайте, попадает ли оно в область щелчка if (! canviewReceivepointerevents (ребенок) ||! istransformedtouchpointinview (x, y, gild, null) {ev.setargetAccesbessibocusFockeScusFockCusFockeScusFockCusfockeCusFockeCusFockCusFontInview продолжать; } // может обрабатывать, обработал ли представление этого указателя предыдущий указатель, а затем использовать newtouchtarget = getTouchTarget (Child); if (newtouchtarget! = null) {// ребенок уже получает прикосновение в пределах своих границ. // Дайте ему новый указатель в дополнение к тем, которые он обрабатывает. newtouchtarget.pointeridbits | = idbitstoassign; перерыв; }} // Внимание 3: отправьте его непосредственно в представление ребенка if (dispatchtransformedtouchevent (ev, false, kild, idbitstoassign)) {// ребенок хочет получить прикосновение в пределах своих границ. mlastTouchDowntime = ev.GetDownTime (); if (предварительный заказ! = null) {// childindex указывает в предварительно предсказанный список, найдите оригинальный индекс для (int j = 0; j <childrencount; j ++) {if (childraindex] == mChildren [j]) {mlastTouchdownIndex = J; перерыв; }}} else {mlastTouchdownIndex = ChildIndex; } mlastTouchdownx = ev.getx (); mlasttouchdowny = ev.gety (); newtouchtarget = addtouchtarget (child, idbitstoassign); уже ispatchedTonewtouchtarget = true; перерыв; }}}}}} // представление ребенка, получающее событие, было найдено ранее. Если он нулевой, это означает, что нет никакого представления о ребенке. Текущая группа View Group должна обрабатывать if (mfirsttouchtarget == null) {// wiewgroup grangle = dispatchtransformedtouchevent (ev, cancelchild, null, touchtarget.all_pointer_ids); } else {if (flaydispatchedTonewtouchtarget) {// игнорировать какой -то код if (dispatchtransformedTouchEvent (ev, cancelChild, target.child, target.pointeridbits)) {обработанное = true; }}} return обрабатывается;}Внимание в приведенном выше коде будет участвовать в более поздней части, поэтому обратите на нее внимание.
Здесь следует указать, что различные указатели в серии действий могут быть назначены различным представлениям для ответа. ViewGroup будет поддерживать указатель и список TouchTargets, которые обрабатывают представления. TouchTarget представляет собой подвесок, который может обрабатывать указатели. Конечно, представление может обрабатывать несколько указателей, такие как оба пальца, находятся в области подвизы. TouchTarget использует Int Internal для хранения PointerId, который он может обрабатывать, и биты Int32, поэтому верхний слой может разрешить только до 32 точек ощущения одновременно.
Давайте посмотрим на код в внимании 3. Мы часто говорим, что если DispatchTouchEvent представления возвращает false, то за ним не может быть действие. Почему это? Потому что, если false возвращается при внимании 3, то это не будет записано в TouchTarget, ViewGroup считает, что у вас нет возможности справиться с этим событием.
Здесь вы можете увидеть, что ViewGroup действительно обрабатывает события в DispatchTransforsedTouchEvent, следуйте и посмотрите:
DispatchTransformedTouchEventPrivate Boolean DispatchTransformedTouchEvent (событие MotionEvent, Boolean Cancel, View Child, int DesirePointerIdbits) {// Обработка без подкласса, а затем оставьте его в View Group для обработки if wild == null) {Handled = super.DispatchTouchEvent (TransformedEvent); } else {final float offsetx = mscrollx - child.mleft; final float offsety = mscrolly - child.mtop; TransformedEvent.OffSetLocation (OffSetEx, OffSety); if (! Child.hasidentityMatrix ()) {TransformedEvent.Transform (child.getInverseMatrix ()); } обработка = child.dispatchtouchevent (transformedevent); } return обрабатывается;}Вы можете видеть, что, несмотря ни на что, будет вызван диспетчертоушюст.
DispatchTouchEvent public Boolean DispatchTouchEvent (Event MotionEvent) {if (onfilterTouchEventForseCurity (Event)) {// Получить событие OnTouch представления сначала, если OnTouch возвращает истинную прослушивание li = mlistenerinfo; if (li! = null && li.montouchlister! = null && (mviewflags & enabled_mask) == Enabled && li.montouchLister.ontouch (this, event)) {result = true; } if (! result && ontouchevent (event)) {result = true; }} return result; }Событие Ontouch, которое мы установили для представления, находится в более высоком приоритете. Если выполнение OnTouch возвращает True, то OnTouchEvent представления не пойдет на представление. Некоторые из наших событий кликов обрабатываются в OntouchEvent, поэтому OnTouch возвращает True, и связанные с кликами события представления не будут обработаны.
Краткое краткое изложение этого процесса
Когда ViewGroup принимает события, передаваемые начальством, если это начало серии сенсорных событий (action_down), ViewGroup сначала проверит, необходимо ли ему перехватить событие (OnInterceptTouchEvent, реализация группы ViewGroup непосредственно возвращает FALSE, чтобы указывать, что оно не перехватывает), и затем ViewGroup проходит все свои представления. Найдите представление, которое вы нажимаете в настоящее время, и сразу же вызовите DispatchTouchEvent представления Target. Если DispatchTouchEvent представления цели возвращает false, то он думает, что целевой вид находится только в этой позиции. Он не хочет принимать это событие, но просто хочет тихо представить (я тихо смотрю, как вы притворяетесь*). В настоящее время ViewGroup также перейдет в DispatchTouchEvent, сделанный!