真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

android事件分發(fā),安卓 事件分發(fā)

Android事件分發(fā)機制

Android中對視圖的Touch事件進(jìn)行分發(fā)處理。

員工經(jīng)過長期磨合與沉淀,具備了協(xié)作精神,得以通過團(tuán)隊的力量開發(fā)出優(yōu)質(zhì)的產(chǎn)品。成都創(chuàng)新互聯(lián)堅持“專注、創(chuàng)新、易用”的產(chǎn)品理念,因為“專注所以專業(yè)、創(chuàng)新互聯(lián)網(wǎng)站所以易用所以簡單”。公司專注于為企業(yè)提供網(wǎng)站建設(shè)、成都做網(wǎng)站、微信公眾號開發(fā)、電商網(wǎng)站開發(fā),重慶小程序開發(fā)公司,軟件按需網(wǎng)站策劃等一站式互聯(lián)網(wǎng)企業(yè)服務(wù)。

單手指操作:ACTION_DOWN - ACTION_MOVE - ACTION_UP

多手指操作:ACTION_DOWN - ACTION_POINTER_DOWN - ACTION_MOVE - ACTION_POINTER_UP - ACTION_UP.

(1) dispatchTouchEvent() :事件分發(fā)

(2) onInterceptTouchEvent() :事件攔截

(3) onTouchEvent() :事件處理

ViewGroup 的相關(guān)事件有三個:onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent。

View 的相關(guān)事件只有兩個:dispatchTouchEvent、onTouchEvent。

先分析ViewGroup的處理流程:首先得有個結(jié)構(gòu)模型概念:ViewGroup和View組成了一棵樹形結(jié)構(gòu),最頂層為Activity的ViewGroup,下面有若干的ViewGroup節(jié)點,每個節(jié)點之下又有若干的ViewGroup節(jié)點或者View節(jié)點,依次類推。如圖:

點擊事件達(dá)到頂級 View(一般是一個 ViewGroup),會調(diào)用 ViewGroup 的 dispatchTouchEvent 方法,如果頂級 ViewGroup 攔截事件即 onInterceptTouchEvent 返回 true,則事件由 ViewGroup 處理,這時如果 ViewGroup 的 mOnTouchListener 被設(shè)置,則 onTouch 會被調(diào)用,否則 onTouchEvent 會被調(diào)用。也就是說如果都提供的話,onTouch 會屏蔽掉 onTouchEvent。在 onTouchEvent 中,如果設(shè)置了 mOnClickListenser,則 onClick 會被調(diào)用。如果頂級 ViewGroup 不攔截事件,則事件會傳遞給它所在的點擊事件鏈上的子 View,這時子 View 的 dispatchTouchEvent 會被調(diào)用。如此循環(huán)。

Android View 事件分發(fā)機制

Android 事件機制包含系統(tǒng)啟動流程、輸入管理(InputManager)、系統(tǒng)服務(wù)和 UI 的通信(WindowManagerService + ViewRootImpl + Window)、事件分發(fā)等一系列的環(huán)節(jié)。

Android 系統(tǒng)中將輸入事件定義為 InputEvent,根據(jù)輸入事件的類型又分為了 KeyEvent(鍵盤事件) 和 MotionEvent(屏幕觸摸事件)。這些事件統(tǒng)一由系統(tǒng)輸入管理器 InputManager 進(jìn)行分發(fā)。

在系統(tǒng)啟動的時候,SystemServer 會啟動 WindowManagerService,WMS 在啟動的時候通過 InputManager 來負(fù)責(zé)監(jiān)控鍵盤消息。

InputManager 負(fù)責(zé)從硬件接收輸入事件,并將事件通過 ViewRootImpl 分發(fā)給當(dāng)前激活的窗口處理,進(jìn)而分發(fā)給 View。

Window 和 InputManagerService 之間通過 InputChannel 來通信,底層通過 socket 進(jìn)行通信。

Android Touch 事件的基礎(chǔ)知識:

KeyEvent 對應(yīng)了鍵盤的輸入事件;MotionEvent 就是手勢事件,鼠標(biāo)、筆、手指、軌跡球等相關(guān)輸入設(shè)備的事件都屬于 MotionEvent。

InputEvent 統(tǒng)一由 InputManager 進(jìn)行分發(fā),負(fù)責(zé)與硬件通信并接收輸入事件。

system_server 進(jìn)程啟動時會創(chuàng)建 InputManagerService 服務(wù)。

system_server 進(jìn)程啟動時同時會啟動 WMS,WMS 在啟動的時候就會通過 IMS 啟動 InputManager 來監(jiān)控鍵盤消息。

App 端與服務(wù)端建立了雙向通信之后,InputManager 就能夠?qū)a(chǎn)生的輸入事件從底層硬件分發(fā)過來,Android 提供了 InputEventReceiver 類,以接收分發(fā)這些消息:

Window 和 IMS 之間通過 InputChannel 通信。InputChannel 是一個 pipe,底層通過 socket 進(jìn)行通信。在 ViewRootImpl.setView() 過程中注冊 InputChannel。

Android 事件傳遞機制是 先分發(fā)再處理 ,先由外部的 View 接收,然后依次傳遞給其內(nèi)層的 View,再從最內(nèi)層 View 反向依次向外層傳遞。

三個方法的關(guān)系如下:

分發(fā)事件:

應(yīng)用了樹的 深度優(yōu)先搜索算法 (Depth-First-Search,簡稱 DFS 算法),每個 ViewGroup 都持有一個 mFirstTouchTarget, 當(dāng)接收到 ACTION_DOWN 時,通過遞歸遍歷找到 View 樹中真正對事件進(jìn)行消費的 Child,并保存在 mFirstTouchTarget 屬性中,依此類推組成一個完整的分發(fā)鏈。在這之后,當(dāng)接收到同一事件序列的其它事件如 ACTION_MOVE、ACTION_UP 時,則會跳過遞歸流程,將事件直接分發(fā)給下一級的 Child。

ViewGroup 分發(fā)事件的主要的任務(wù)是找一個 Target,并且用這個 Target 處理事件,主要邏輯如下 :

為什么倒序查找 TouchTarget?

如果按添加順序遍歷,當(dāng) View 重疊時(FrameLayout),先添加的 View 總是能消費事件,而后添加的 View 不可能獲取到事件。

攔截事件:

[1] Android 事件分發(fā)機制的設(shè)計與實現(xiàn)

[2] Android 事件攔截機制的設(shè)計與實現(xiàn)

Android TV 按鍵焦點事件分發(fā)流程詳解

DecorView →PhoneWindow →Activity→ViewGroup→view

下面我們根據(jù)按鍵事件的分發(fā)流程,抽絲剝繭,逐一分析。

private int processKeyEvent(QueuedInputEvent q)

1、DecorView.java

2、Activity.java

3、ViewGroup.java

4、View.java

通過該方法,接收器receiver的onKeyDown、onKeyUp、onKeyLongPress、onKeyMultiple等方法將被回調(diào)。

在上述按鍵事件的入口中提到的ViewRootImpl中

如果mView.dispatchKeyEvent(event)返回true,則結(jié)束事件分發(fā);

如果返回false,則調(diào)用如下方法

繼續(xù)執(zhí)行后續(xù)的焦點導(dǎo)航流程。

焦點導(dǎo)航的總體流程就是:

1、View focused = mView.findFocus();//從視圖樹的頂層,即DecorView一層一層的遞歸查找當(dāng)前獲得焦點的view

2、View v = focused.focusSearch(direction);根據(jù)導(dǎo)航的方向查找下一個可獲取焦點的view

3、v.requestFocus(direction, mTempRect)請求獲取焦點

4、v.requestFocus(direction,mTempRect)內(nèi)部,調(diào)用mParent.requestChildFocus(this, focused)逐層遞歸向上級通知

ViewRootImpl.java

mView即DecorView,從DecorView開始,一層一層的向下遞歸查找當(dāng)前獲得焦點的view

找到了當(dāng)前獲得焦點的focused,調(diào)用該焦點view的focusSearch(direction)方法查找direction方向上下一個將要獲取焦點的view。

focused.focusSearch(direction)實際上會調(diào)用mParent.focusSearch(this, direction)方法,層層遞歸,直到調(diào)用到DecorView的focusSearch(this, direction)方法。

而DecorView繼承ViewGroup,實際上最終會調(diào)用到FocusFinder.getInstance().findNextFocus(this, focused, direction),this 就是DecorView對象。

最終會調(diào)用到DecorView父類ViewGroup中的FocusFinder.getInstance().findNextFocus(this, focused, direction);

ViewGroup.java

FocusFinder.java

搜索到下一個獲取焦點的view后,調(diào)用該view.requestFocus(direction, mTempRect)方法

注意:調(diào)用requestFocus(direction, mTempRect)需要區(qū)分調(diào)用者。

如果是ViewGroup,則會更加焦點獲取策略,實現(xiàn)父View和子View之間獲取焦點的優(yōu)先級。

如下是ViewGroup.java 和View.java 中requestFocus方法是實現(xiàn):

ViewGroup.java

View.java

View獲取到焦點后,會調(diào)用mParent.requestChildFocus(this, focused)逐層遞歸向上級通知

ViewGroup.java


分享標(biāo)題:android事件分發(fā),安卓 事件分發(fā)
本文路徑:http://weahome.cn/article/dsddjip.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部