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,那么就会出现异常
"
+ "ViewGroup root and attachToRoot=true"
【2】如果爸爸和标识符都是正常的,那么继续使用递归的方式,遍历它的所有孩子
void rInflate(XmlPullParser parser, View parent, Context context, AttributeSet attrs, boolean finishInflate)
1.获取解析器当前元素的深度
Outside startTag 0
startTag 1
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:如果是
其他情况:首先创建出子View,拿到爸爸的布局参数,继续遍历自己的子View,遍历之后,爸爸将其加入到自己的孩子当中。
6.如果name不是merge的话,
【1】创建出子 View的实例(创建子View的时候,用到了工厂模式)
【2】如果爸爸不是null,获取到爸爸的布局参数,如果不需要绑定到爸爸上,那么将参数设置给子View
【3】子 View去遍历自己的孩子
【4】如果爸爸不是null而且需要去将子View绑定在爸爸上,那么将子 View和布局参数一起加入到爸爸的孩子当中
【5】如果爸爸是空的或者不需要进行绑定,那么子View就是我们需要返回的那个View,将其赋值给result
7.返回result
源码阅读笔记暂存,之后会将其写成博客。