91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中如何實現View事件分發

發布時間:2022-04-08 16:23:22 來源:億速云 閱讀:177 作者:iii 欄目:編程語言

這篇文章主要講解了“Android中如何實現View事件分發”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Android中如何實現View事件分發”吧!

(1)ViewGroup.dispatchTouchEvent(event)

boolean dispatchTouchEvent(MotionEvent event) {
 int action = event.getAction();

 //判斷ViewGroup是否攔截touch事件。當為ACTION_DOWN或者找到能夠接收touch事件的子View
 時,由onInterceptTouchEvent(event)決定是否攔截。其他情況,即ACTION_MOVE/ACTION_UP且
 沒找到能夠接收touch事件的子View時,直接攔截。
 boolean intercepted;
 if (action == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) {
  intercepted = onInterceptTouchEvent(event);
 } else {
  intercepted = true;
 }

 //如果ViewGroup不攔截touch事件。在ACTION_DOWN時遍歷所有子View,查找能夠接收touch事件的
 子View。如果找到則設置mFirstTouchTarget,并跳出循環。
 boolean alreadyDispatchedToNewTouchTarget = false;
 if (!intercepted) {
  if (action == MotionEvent.ACTION_DOWN) {
   for (int i = childrenCount - 1; i >= 0; i--) {
    if (!canViewReceivePointerEvents(child) ||
     !isTransformedTouchPointInView(x, y, child, null)) {
      continue;
    }
    if (dispatchTransformedTouchEvent(event, child)) {
     //找到mFirstTouchTarget
     newTouchTarget = addTouchTarget(child);
     alreadyDispatchedToNewTouchTarget = true;
     break;
    }
    }
   }
 }

 //事件下發及消費。如果沒找到能夠接收touch事件的子View,則由ViewGroup自己處理及消費。
 如果找到能夠接收touch事件的子View,則由子View遞歸處理touch事件及消費。
 boolean handled = false;
 if (mFirstTouchTarget == null) {
  handled = dispatchTransformedTouchEvent(event, null);
 } else {
  if (alreadyDispatchedToNewTouchTarget) {
   handled = true;
  } else {
   while (touchTarget) {
    handled = dispatchTransformedTouchEvent(event, child);
   }
  }
 }

 return handled;
}


//ViewGroup事件下發。如果無接收touch事件的子View,則由ViewGroup的父類(即View)下發touch事件
如果child非空,則交由子View下發touch事件,子View可以是ViewGroup或View。
boolean dispatchTransformedTouchEvent(MotionEvent event, View child) {
 boolean handled;
 if (child == null) {
  handled = super.dispatchTouchEvent(event);
 } else {
  handled = child.dispatchTouchEvent(event);
 }
 return handled;
}

(2)View.dispatchTouchEvent(event)

//View的Touch事件分發。當外部設置了mOnTouchListener時,先交由mOnTouchListener.onTouch(event)消費。
若未消費,則交給View的onTouchEvent(event)消費。onTouchEvent的實現是,如果設置了mOnClickListener,
則執行mOnClickListener.onClick()點擊事件。返回值為true,表示消費,否則未消費。
boolean dispatchTouchEvent(MotionEvent event) {
 boolean result = false;
 if (mOnTouchListener != null && mOnTouchListener.onTouch(this, event)) {
   result = true;
 }
 if (!result && onTouchEvent(event)) {
  result = true;
 }
 return result;
}


boolean onTouchEvent(MotionEvent event) {
 performClick();
}

3.總結

總結下ViewGroup的事件分發及消費過程:

整個過程包括3個部分:判斷是否攔截 -> 查找接收touch事件的子View -> 事件下發及消費

判斷是否攔截:

(1) ACTION_DOWN 或者 非ACTION_DOWN且找到接收touch事件的子View時,由onInterceptTouchEvent(event)決定是否攔截

(2) 非ACTION_DOWN,且未找到接收touch事件的子View時,標明需要攔截touch事件

這里解釋下,影響ViewGroup是否能攔截touch事件有2個因素:是否 找到了接收touch事件的子View 和 onInterceptTouchEvent(event). 而查找接收touch事件的子View這一過程只需要在ACTION_DOWN的時候確定好就行。如果ACTION_DOWN的時候沒找到,那么ACTION_MOVE和ACTION_UP肯定也找不到,因此touch事件直接被ViewGroup攔截。如果找到了接收touch事件的子View,那么ACTION_MOVE和ACTION_UP情況下還是要檢查下ViewGroup的onInterceptTouchEvent(event),看下是否攔截。

查找接收touch事件的子View:

(1) 兩種情況下查找:ACTION_DOWN且ViewGroup不攔截的情況下。

(2) 查找方法:遍歷所有子View,如果touch事件的xy坐標在該ViewGroup的某個子View范圍內,則針對該子View執行遞歸分發touch事件操作,如果找到有子View處理touch事件(return true),則跳出循環。

這里解釋下查找條件。查找接收touch事件的子View,顯然只需要ACTION_DOWN情況下即可,沒必要ACTION_MOVE和ACTION_UP都檢查,否則重復操作。如果ViewGroup都已經攔截了,顯然不需要再去考慮子View怎么樣了。

事件下發及消費:

(1)兩種情況:ViewGroup下發及消費 或者 ViewGroup的子View下發及消費

(2)如果經過以上兩步,沒找到接收Touch事件的子View,那么由ViewGroup進行下發及消費,下發及調用流程是:ViewGroup.dispatchTouchEvent -> View.dispatchTouchEvent -> mOnTouchListener.onTouch -> onTouchEvent -> onClick

(3)如果找到接收touch事件的子View,則針對該子View執行touch事件遞歸下發及消費的操作

補充:

(1) 源碼中,mFirstTouchEvent表示接收touch事件的子View

(2) 步驟2和3,都有執行dispatchTransformedTouchEvent(event, child)的操作,步驟2中只是為了查找接收touch事件的子View,步驟3主要目的是進行事件分發及消費。如果步驟2中針對某個子View已經執行了該方法,則步驟3中不再重復執行。個人理解,不知道是否有誤。

4.結論

(1) 回調方法

ViewGroup:dispatchTouchEvent -> onInterceptTouchEvent -> onTouchEvent

View: dispatchTouchEvent -> onTouch

(2) 調用順序

Action執行順序:ACTION_DOWN -> ACTION_MOVE -> ACTION_UP

ViewGroup: dispatchTouchEvent -> onInterceptTouchEvent -> onTouchEvent()

View: dispatchTouchEvent -> onTouchEvent

事件分發傳遞順序: Parent View -> Child View

ViewGroup1.dispatchTouchEvent -> ViewGroup2.dispatchTouchEvent
-> View3.dispatchTouchEvent
(緊跟著是View3.onTouchEvent)

事件消費傳遞順序:Child View -> Parent View

View3.onTouchEvent -> ViewGroup2.onTouchEvent
-> ViewGroup1.onTouchEvent

感謝各位的閱讀,以上就是“Android中如何實現View事件分發”的內容了,經過本文的學習后,相信大家對Android中如何實現View事件分發這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

三台县| 廊坊市| 新建县| 老河口市| 洛阳市| 英德市| 湛江市| 乐平市| 阿拉善左旗| 舞阳县| 福州市| 临汾市| 凭祥市| 石柱| 修武县| 延边| 永年县| 清新县| 保山市| 马边| 台安县| 南丰县| 文昌市| 海口市| 宕昌县| 民和| 抚松县| 铜陵市| 沁阳市| 昆山市| 宿迁市| 德清县| 松原市| 绿春县| 卢氏县| 中宁县| 铜鼓县| 萨迦县| 富锦市| 永宁县| 宁河县|