View繪製流程源碼分析-第二篇

關於:getLayoutInflater().inflate,這是自己看源碼的筆記,作爲記錄篇,最近會將其整理出來

activity.getlayoutinflater

getWindow(PhoneWindow).getlayoutinflater

初始化:
PhoneWindow
public PhoneWindow(Context context) {
super(context);
mLayoutInflater = LayoutInflater.from(context);
}

LayoutInflater
LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

解析 layoutinflater.inflate
四個重載方法

重點在於:
LayoutInflater.inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot)

這個函數裏面的邏輯:

前傳:將root節點先賦值給result
1.尋找根節點,如果既不是 開始標籤 也不是 結束標籤 一直循環,解析器指向下一個標籤一直到跳出循環爲止

2.跳出循環之後,對type進行檢查,正常的流程肯定是先遇到 開始標籤,如果不是,拋出佈局異常,提示沒有找到 start tag

3.獲取到當前解析器指向的標籤名稱name

4.如果是可調式模式,打印出當前的根節點

5.如果name是merge的話,也就是start tag是,說明一定需要綁定到一個爸爸上面
【1】如果此時爸爸是空的,或者需要綁定的標識符是false,那麼就會出現異常
" can be used only with a valid "
+ “ViewGroup root and attachToRoot=true”
【2】如果爸爸和標識符都是正常的,那麼繼續使用遞歸的方式,遍歷它的所有孩子

void rInflate(XmlPullParser parser, View parent, Context context, AttributeSet attrs, boolean finishInflate)
1.獲取解析器當前元素的深度
Outside startTag 0
startTag 1
2
2
endTag 1
OutSide endTag 0
2.如果當前的節點不是endtag或者深度大於第一次獲取的depth, 同時當前的type不是END_DOCUMENT(針對XML文檔),進入循環
如果不是starttag,進入下一輪循環
獲取當前解析器的元素名稱,
TAG_REQUEST_FOCUS:???
TAG_TAG:爲設置parent設置tag
TAG_INCLUDE:如果當前的getDepth是0的話,那麼就會拋出異常,根節點不能是標籤
如果不是的話,首先獲取到爸爸的layoutParams,然後將其設置給子View,子View再去遍歷自己的孩子,遍歷之後 爸爸將子View加入到自己的孩子當中。
TAG_MERGE:如果是拋出異常,必須是根節點才能是merge標籤,現在遍歷都是子View
其他情況:首先創建出子View,拿到爸爸的佈局參數,繼續遍歷自己的子View,遍歷之後,爸爸將其加入到自己的孩子當中。

6.如果name不是merge的話,
【1】創建出子 View的實例(創建子View的時候,用到了工廠模式)
【2】如果爸爸不是null,獲取到爸爸的佈局參數,如果不需要綁定到爸爸上,那麼將參數設置給子View
【3】子 View去遍歷自己的孩子
【4】如果爸爸不是null而且需要去將子View綁定在爸爸上,那麼將子 View和佈局參數一起加入到爸爸的孩子當中
【5】如果爸爸是空的或者不需要進行綁定,那麼子View就是我們需要返回的那個View,將其賦值給result

7.返回result

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章