偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Android View焦點總結

移動開發(fā) Android
Android焦點相關邏輯大部分都在都在View, ViewGroup和FocusFinder三個類中。View對象都有一個mParent變量(添加到ViewGroup后), 代指其父容器. 絕大部分View的mParent都是ViewGroup類型, 除了根節(jié)點。一個Window中View根節(jié)點DecorView的mParent稱為ViewRoot, 在安卓4.0后ViewRoot對應ViewRootImpl, 它不是View的子類, 而是個ViewParent。

Android View焦點

Android焦點相關邏輯大部分都在都在View, ViewGroup和FocusFinder三個類中.

ViewRoot

View對象都有一個mParent變量(添加到ViewGroup后), 代指其父容器. 絕大部分View的mParent都是ViewGroup類型, 除了根節(jié)點. 一個Window中View根節(jié)點DecorView的mParent稱為ViewRoot, 在安卓4.0后ViewRoot對應ViewRootImpl, 它不是View的子類, 而是個ViewParent. ViewRootImpl是連接Window和DecorView的紐帶, View的焦點, 按鍵, 布局, 渲染等流程都是從ViewRoot中開始的.

View的焦點

基本流程如下

 

 

View(包括ViewGroup)獲取焦點都通過如下三個方法

View.java 

 

 

 

從上面可以看到前兩個最終會執(zhí)行到第三個方法.

***的requestFocusNoSearch先判斷是否可以獲取焦點, 然后進入下面的***流程:

View.java 

 

 

 

上面的流程比較簡單: 如果當前沒有焦點, 先置焦點標志, 再通知parent, 然后刷新圖片.

主要的流程在mParent的requestChildFocus里面, 后面會分析. 那里會逐層向上修改焦點View并清除原來有焦點的View的焦點

onFocusChange會觸發(fā)invalidate刷新, 然后調用onFocusChangeListener. 默認情況每個View只能設置一個onFocusChangeListener, 而開發(fā)中經常遇到需要設置多個Listener的情況, 我們就可以重寫onFocusChange方法, 實現回調多個onFocusChangeListener的需求.

ViewGroup的焦點

ViewGroup獲取焦點是在View獲取焦點流程中多了內部焦點處理

ViewGroup.java 

 

 

 

上面代碼中descendantFocusability決定了是先按View焦點流程處理(自己處理焦點)還是先把給子View處理

FOCUS_BLOCK_DESCENDANTS 不允許子View獲取焦點, 那么按照View的流程進行

FOCUS_BEFORE_DESCENDANTS 先按照View的流程處理, 如果自己不能獲取焦點則給孩子處理

FOCUS_AFTER_DESCENDANTS 先嘗試給孩子焦點, 如果沒有可獲取焦點再按照View流程自己獲取焦點

默認值FOCUS_BEFORE_DESCENDANTS, 我們可以通過setDescendantFocusability(int d)

設置

onRequestFocusInDescendants方法是給子類重寫使用, 可以控制子View處理焦點. 默認按照子View順序處理, direction向下或向右則從***個開始, 向上或向左則從***一個開始, 直到某個子View獲取焦點

注意此方法只在此ViewGroup及其上層View上調用requestFocus時會執(zhí)行到

父容器焦點的處理

在View獲取焦點流程中會調用mParent.requestChildFocus, 維護View樹上焦點唯一, 在各層ViewGroup中保存有焦點的子View

ViewGroup.java 

 

 

 

先清除自己的焦點, 如果原來內部有焦點, 先清除其焦點, 保存獲取焦點的孩子, 然后調用上一層的requestChildFocus. ***的調用可知, 這個方法會一直調用到View的樹的root節(jié)點.

在當前ViewGroup內部, 任何一個孩子取得焦點都會執(zhí)行到這個方法, 因此此方法也是ViewGroup得知孩子焦點變化的方法之一.(可惜不能得知孩子失去焦點)

失去焦點或清除焦點

獲取焦點可以是主動的, 但失去焦點一般都是被動的(見上面的代碼), 因此邏輯相對簡單, 只要清除焦點狀態(tài)即可.

ViewGroup.java 

 

 

 

View.java

 

 

注意上面的方法是默認package訪問級別的, 我們無法重寫也不能調用

也可以主動清除焦點, 與獲取焦點流程相似

ViewGroup.java 

 

 

 

View.java 

 

 

 

ViewGroup.java

以上是安卓View系統焦點處理的全部流程和涉及到的方法, ViewRootImpl的requestChildFocus和clearChildFocus實現我們不需要關注

另外還有以下一些輔助方法

boolean isFocusable() View是否可以獲取焦點

boolean isFocused() View是否獲取焦點

boolean hasFocus() View/ViewGroup內部是否有焦點

View findFocus() 取到View/ViewGroup內部的焦點View

View getFocusedChild() 取到ViewGroup內部有焦點的子View

View getRootView() 取到根節(jié)點View(一般是DecorView或頂層ViewGroup)

焦點移動

除了在代碼里面控制焦點, 系統對沒有處理的方向鍵等一些按鍵自動按照焦點移動來處理, 見下面代碼

ViewRootImpl.java 

 

 

 

 

 

 

代碼比較上, 但是主要做了三個步驟

如果View沒有處理按鍵, 把上下左右tab等按鍵轉換成對應方向

在當前焦點View上通過focusSearch方法查找對應方向的下一個View

查找到的View調用requestFocus因此主要的流程在focusSearch中

View.java 

 

 

 

普通View查找什么都沒做, 交給parent來完成.

ViewGroup.java 

 

 

 

ViewRootImpl 

 

 

 

 

我們可以重寫focusSearch控制焦點移動順序, 而默認的焦點移動順序由FocusFinder決定

FocusFinder查找焦點

FocusFinder為public的工具類, 主要就兩個方法, 可以在給定的View內在指定方向查找指定View或坐標的下一個焦點如下: 

 

 

 

核心邏輯就兩步, 先查找setNextFocusXXId設置的View, 如果沒有按照就近算法查找.具體算法不再分析, SDK里面有源碼.

總結

綜合上面的流程分析, 我們在實現自定義View時, 對焦點的特殊需求有如下思路

requestFocus和clearFocus直接對View清除或轉移焦點

除了onFocusChangeListener, 還可以在onFocusChange方法中實現一些View失去/獲得焦點時通知

對ViewGroup, 如果只需要在子View獲取焦點時得到通知, 有requestChildFocus方法.

重寫onRequestFocusInDescendants方法可以控制某些情景下ViewGroup焦點

控制焦點移動可以重寫focusSearch方法

另外還有FocusFinder工具和上面的輔助方法.

責任編輯:龐桂玉 來源: Android開發(fā)中文站
相關推薦

2017-12-28 14:51:01

AndroidView焦點

2016-03-14 09:43:47

androidview總結

2013-07-16 14:47:18

Android EdiEditText不彈出Android開發(fā)

2011-01-26 10:21:30

view類Qt

2017-03-14 15:09:18

AndroidView圓形進度條

2011-12-23 10:17:25

Android音樂編程管理音頻焦點

2016-11-16 21:55:55

源碼分析自定義view androi

2016-12-26 15:25:59

Android自定義View

2014-07-29 15:57:01

ContentProv

2010-01-27 16:41:48

Android特點

2017-03-07 13:03:34

AndroidView知識問答

2016-04-12 10:07:55

AndroidViewList

2010-01-27 17:45:15

Android應用技巧

2010-01-26 17:05:37

Android缺點

2011-11-04 16:34:20

控件Android

2016-12-12 14:55:01

AndroidAndroid Vie

2017-08-21 21:36:23

AndroidViewJava

2018-01-09 15:57:18

熱修復開發(fā)編譯

2010-01-25 15:10:08

Android組件

2010-01-27 10:45:32

Android快速啟動
點贊
收藏

51CTO技術棧公眾號