精品专区-精品自拍9-精品自拍三级乱伦-精品自拍视频-精品自拍视频曝光-精品自拍小视频

網站建設資訊

NEWS

網站建設資訊

android焦點,Android焦點監聽

Android TV 按鍵焦點事件分發流程詳解

DecorView →PhoneWindow →Activity→ViewGroup→view

專注于為中小企業提供成都做網站、成都網站設計服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業淳安免費做網站提供優質的服務。我們立足成都,凝聚了一批互聯網行業人才,有力地推動了近千家企業的穩健成長,幫助中小企業通過網站建設實現規模擴充和轉變。

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

private int processKeyEvent(QueuedInputEvent q)

1、DecorView.java

2、Activity.java

3、ViewGroup.java

4、View.java

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

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

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

如果返回false,則調用如下方法

繼續執行后續的焦點導航流程。

焦點導航的總體流程就是:

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

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

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

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

ViewRootImpl.java

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

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

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

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

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

ViewGroup.java

FocusFinder.java

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

注意:調用requestFocus(direction, mTempRect)需要區分調用者。

如果是ViewGroup,則會更加焦點獲取策略,實現父View和子View之間獲取焦點的優先級。

如下是ViewGroup.java 和View.java 中requestFocus方法是實現:

ViewGroup.java

View.java

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

ViewGroup.java

Android TV 焦點原理源碼解析

相信很多剛接觸AndroidTV開發的開發者,都會被各種焦點問題給折磨的不行。不管是學技術還是學習其他知識,都要學習和理解其中原理,碰到問題我們才能得心應手。下面就來探一探Android的焦點分發的過程。

Android焦點事件的分發是從ViewRootImpl的processKeyEvent開始的,源碼如下:

源碼比較長,下面我就慢慢來講解一下具體的每一個細節。

dispatchKeyEvent方法返回true代表焦點事件被消費了。

ViewGroup的dispatchKeyEvent()方法的源碼如下:

(2)ViewGroup的dispatchKeyEvent執行流程

(3)下面再來瞧瞧view的dispatchKeyEvent方法的具體的執行過程

驚奇的發現執行了onKeyListener中的onKey方法,如果onKey方法返回true,那么dispatchKeyEvent方法也會返回true

可以得出結論:如果想要修改ViewGroup焦點事件的分發,可以這么干:

注意:實際開發中,理論上所有焦點問題都可以通過給dispatchKeyEvent方法增加監聽來來攔截來控制。

(1)dispatchKeyEvent方法返回false后,先得到按鍵的方向direction值,這個值是一個int類型參數。這個direction值是后面來進行焦點查找的。

(2)接著會調用DecorView的findFocus()方法一層一層往下查找已經獲取焦點的子View。

ViewGroup的findFocus方法如下:

View的findFocus方法

說明:判斷view是否獲取焦點的isFocused()方法, (mPrivateFlags PFLAG_FOCUSED) != 0 和view 的isFocused()方法是一致的。

其中isFocused()方法的作用是判斷view是否已經獲取焦點,如果viewGroup已經獲取到了焦點,那么返回本身即可,否則通過mFocused的findFocus()方法來找焦點。mFocused其實就是ViewGroup中獲取焦點的子view,如果mView不是ViewGourp的話,findFocus其實就是判斷本身是否已經獲取焦點,如果已經獲取焦點了,返回本身。

(3)回到processKeyEvent方法中,如果findFocus方法返回的mFocused不為空,說明找到了當前獲取焦點的view(mFocused),接著focusSearch會把direction(遙控器按鍵按下的方向)作為參數,找到特定方向下一個將要獲取焦點的view,最后如果該view不為空,那么就讓該view獲取焦點。

(4)focusSearch方法的具體實現。

focusSearch方法的源碼如下:

可以看出focusSearch其實是一層一層地網上調用父View的focusSearch方法,直到當前view是根布局(isRootNamespace()方法),通過注釋可以知道focusSearch最終會調用DecorView的focusSearch方法。而DecorView的focusSearch方法找到的焦點view是通過FocusFinder來找到的。

(5)FocusFinder是什么?

它其實是一個實現 根據給定的按鍵方向,通過當前的獲取焦點的View,查找下一個獲取焦點的view這樣算法的類。焦點沒有被攔截的情況下,Android框架焦點的查找最終都是通過FocusFinder類來實現的。

(6)FocusFinder是如何通過findNextFocus方法尋找焦點的。

下面就來看看FocusFinder類是如何通過findNextFocus來找焦點的。一層一層往下看,后面會執行findNextUserSpecifiedFocus()方法,這個方法會執行focused(即當前獲取焦點的View)的findUserSetNextFocus方法,如果該方法返回的View不為空,且isFocusable = true isInTouchMode() = true的話,FocusFinder找到的焦點就是findNextUserSpecifiedFocus()返回的View。

(7)findNextFocus會優先根據XML里設置的下一個將獲取焦點的View ID值來尋找將要獲取焦點的View。

看看View的findUserSetNextFocus方法內部都干了些什么,OMG不就是通過我們xml布局里設置的nextFocusLeft,nextFocusRight的viewId來找焦點嗎,如果按下Left鍵,那么便會通過nextFocusLeft值里的View Id值去找下一個獲取焦點的View。

可以得出以下結論:

1. 如果一個View在XML布局中設置了focusable = true isInTouchMode = true,那么這個View會優先獲取焦點。

2. 通過設置nextFocusLeft,nextFocusRight,nextFocusUp,nextFocusDown值可以控制View的下一個焦點。

Android焦點的原理實現就這些。總結一下:

為了方便同志們學習,我這做了張導圖,方便大家理解~

Android焦點問題

Android焦點分發主要涉及的方法就是

findFocus:View都有,發現焦點

requestFocus:View都有,請求獲取焦點

requestChildFocus:只有ViewGroup有

focusSearch:View都有,焦點查詢

這幾個方法下面將分別介紹一下這幾個方法。

1、焦點的獲取,默認進入頁面

系統自動請求焦點也是從最頂層的容器控件開始向內請求的,我們進入一個界面系統會自動請求焦點,尋找焦點,最后使用一個控件獲得焦點。

2、焦點的切換

切換焦點的時候,也是要從最頂層的父容器尋找到焦點(findFocus),然后從獲得到焦點的控件開始從內向外調用focusSearch尋找下一個焦點控件。

總結:Android的焦點分發跟事件分發類似,有一個從內向外,從外向內的過程,焦點分發中,尋找當前的焦點控件(findFocus)和焦點的請求(requestChildFocus)都是從外向內的,就是從頂層的父容向內層的子容器尋找和請求,但是搜尋下一個焦點(focusSearch)是從當前焦點控件開始的,就是從內向外尋找,到這里我們知道了Android焦點分發的一個基本流程。

參考 Android TV 按鍵焦點事件分發流程詳解

Android 輸入法窗口焦點獲取流程(2) ,輸入法窗口和應用窗口綁定

基于Android9.x

Window和Session創建成功后,窗口的下一步流程為獲取焦點

我們看下焦點獲取過程,跟輸入法相關的流程

兩個Activity切換時,對應的狀態變化過程為:

以下是Activity窗口初次獲取焦點的流程

當兩個activity 切換時,失去焦點的窗口調用過程如下:

對應的,獲取焦點的額窗口的調用過程如下:

當B窗口的狀態切換到RESUMED時,當窗口的focus可能變化時,會調用updateFocusedWindowLocked

在該方法中,判斷,如果還沒有執行startInputInner方法,則執行startInputInner方法,否則,直接執行startInputOrWindowGainedFocus方法

主要流程:

1:設置controlFlags的flag為CONTROL_WINDOW_FIRST

2:檢查是否已經執行過startInputInner,沒有的話執行startInputInner--startInputOrWindowGainedFocus;否則,直接執行startInputOrWindowGainedFocus

兩條路徑,攜帶的startInputReason參數不一樣

主要流程:

1:檢查要啟動和退出的ServedView是否為同一個,如果為同一個,則表示已經執行過startInputInner,則返回false,表示不再執行startInputInner

2:如果獲取焦點的是EditorText,會創建跟IMS通信的mServedInputConnectionWrapper對象

主要流程:

1:創建EditorInfo對象tba,這個參數對TextView布局才有意義,它的初始化是在mServedView的onCreateInputConnection完成實例化的

2:根據EditorInfo創建一個InputConnection對象,輸入法應用通過該對象,完成輸入內容到輸入框的傳遞;ACTIVITY獲取焦點場景,該對象

為null,因為沒有要輸入的對象

startInputOrWindowGainedFocus攜帶的參數

startInputReason = 1

表示,該流程是窗口獲取焦點過程

mClient

應用層創建的IInputMethodClient對象,為服務層提供應用層的各個回調方法

該方法跟應用進程首次創建時Session時,傳遞到IMMS的對象是同一個對象

windowGainingFocus:

應用層的ViewRootImpl$W對象

controlFlags |= CONTROL_START_INITIAL;

表示window窗口剛開始獲取焦點

softInputMode = SOFT_INPUT_ADJUST_RESIZE , 允許調整輸入法窗口,避免被其他窗口遮擋

tba , EditorInfo對象

servedContext

null

missingMethodFlags

ic等于null的情況下,為0

當應用層傳遞的W對象windowToken不為null的時候,則創建windowGainedFocus對象,返回給app

結果返回后,會對IMM的對象進行賦值

如此,進入一個窗口,獲取窗口焦點過程,窗口與輸入法相關的流程,就結束了。

下一篇:輸入法在輸入框彈出流程

Android輸入法(3),彈出流程

Android中 所謂焦點是什么?誰能幫忙解釋一下嗎!

焦點大概就是你當前要操作的地方.

例如,你有三行輸入框,

焦點在第一行輸入框時,你打字就會輸入進第1個輸入框,

焦點在哪個上,字就會輸入到哪里.

android tv常見問題(一)焦點查找規律

Recyclerview聚焦到最后一個Item,繼續按下鍵,焦點保持不變。

Recyclerview聚焦到最后一個Item,繼續按下鍵,焦點會跳出RecyclerView,跳到附近的View上。

那么當Recyclerview滑動到最底部時,按下鍵,Android系統是如何找到下一個需要被聚焦的view的呢?我們把斷點打在ViewGroup的focusSearch方法上,可以看到從ViewRootImp的performFocusNavigation方法開始,依次調用了如下方法。

View并不會直接去找焦點,而是交給它的parent去找。

焦點會逐級的交給父ViewGroup的focusSearch方法去處理,直到最外層的布局,最后實際上是調用了FocusFinder的findNextFocus方法去尋找新的焦點。

但是這里要注意的是,RecyclerView和其他的ViewGroup不一樣,它自己重寫了focusSearch方法。所以在焦點查找委托到達到DecorView之前,會先執行RecyclerView的focusSearch方法。

那么,RecyclerView和其他ViewGroup在尋找焦點方面有什么不一樣呢? 為什么RecyclerView要重寫ViewGroup的焦點查找機制呢 ?想知道這些問題的答案,那我們首先要知道ViewGroup的焦點查找機制。

ViewGroup的焦點查找機制的核心其實就是FocusFinder的findNextFocus方法。

主要步驟:

主要注意三點:

在addFocusables之后,找到指定方向上與當前focused距離最近的view。在進行查找之前,會統一坐標系。

總的來說就是根據當前focused的位置以及按鍵的方向,循環比較focusable集合中哪一個最適合,然后返回最合適的view,焦點查找就算完成了。

用于比較的方法。分別是將 當前聚焦的view , 當前遍歷到的focusable 和 目前為止最合適的focusable (i = 0時是優先級最低的rect)進行比較。

判斷是否可以做為候選。可以看作是一個初步篩選的方法,但是到底哪個更好還需要看beamBeat方法,這個方法會將通過篩選的focusable和當前最合適的focusable進行比較,選出更合適的一個。

到這里為止ViewGroup的focusSearch方法基本上就講完了。那么下面來看一下RecyclerView的focusSearch方法是如何實現焦點查找的。

前面講到了,該方法主要是為了解決 RecyclerView聚焦在按鍵方向上、當前屏幕區域內可見的最后一個item時,當前不可見的下一個item將無法獲得焦點。

這個方法是由LayoutManager來實現的,這就是RecyclerView的針對上面提到的情況的焦點查找方法。這里主要分析LinearLayoutManager中實現的該方法,如果在使用其他的LayoutManager時出現RecyclelerView焦點不符合預期的話,可以查看對于LayoutManager下的onFocusSearchFailed方法。

主要關注findPartiallyOrCompletelyInvisibleChildClosestToEnd方法,通過這個方法的命名我們大致就可以看出來這個方法的作用了。這個方法主要會 根據當前RecyclerVIew的正逆序以及按鍵方向,找出最近一個部分或完全不可見的View 。

這個方法是RecyclerView內部的方法,和FocusFinder中的isCandidate方法的邏輯可以說幾乎是一摸一樣的。

到此為止ViewGroup的focusSearch和RecyclerVIew的focusSearch都分析完了。我們已經知道RecyclerView滑動到最底部的時候,發生了哪些焦點行為,那么解決起來就比較簡單了。

結合KeyEvent事件的流轉,處理焦點的時機,按照優先級(順序)依次是:

以上任一處都可以指定焦點,一旦消費了就不再往下走。

比如前面說到了RecyclerView就是通過重寫focusSearch方法對邊界上部分可見或不可見的view的焦點查找進行了特殊處理。

重寫RecyclerView的focusSearch方法


新聞標題:android焦點,Android焦點監聽
標題來源:http://m.jcarcd.cn/article/dscjchc.html
主站蜘蛛池模板: 日韩一中文字 | 黑人巨大 | 精品免费在线 | 日本啊在线观看 | 午夜欧美福利 | 国自产拍视频 | 国产综合久 | 乱伦亚洲 | 天美传媒在线观看果 | 国产亚洲精品福利 | 日本精品a在线观看 | 91视频一区二区 | 成人污污污w | 国产乱老熟视频网 | 国产理论片免费观看 | 精品国产呦系列在线 | www.色五天| 国产精伦一区 | 绿巨人污视频下载 | 伦理片飘花免费影院 | 日本高清在线精品 | 国产91精品在线 | 日韩午夜成 | 99自拍视频 | 理论精品电影 | 爱豆精品秘国产 | 成人激情视 | 最新热门电视剧 | 日韩欧美一二区 | 国产日产欧产精品 | 日本欧美一区二区 | 国产精品一区二区五 | 国产日韩欧美大片 | 精品国产自产在线 | 精品一区卡2卡3卡 | 青青青爽在 | 国产精品16P | 国产伊煮焦成品75 | 国产专区 | 午夜福利在线观看 | 九九热国产视频精品 |