LayoutInflater 到底怎么把xml添加到decorview
来源:互联网 发布:各大国家的顶级域名 编辑:程序博客网 时间:2024/06/06 04:11
LayoutInflater 到底怎么把xml添加到decorview
Actity调用setContentView时初始化decorview后会根据layoutResID加载布局。
下面是源码加载过程:
PhoneWindow.java:
@Override public void setContentView(int layoutResID) { // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window // decor, when theme attributes and the like are crystalized. Do not check the feature // before this happens. if (mContentParent == null) { installDecor(); } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) { mContentParent.removeAllViews(); } if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) { final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID, getContext()); transitionTo(newScene); } else { mLayoutInflater.inflate(layoutResID, mContentParent); }
LayoutInflater.java:
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { //将布局id和容器id传入 return inflate(resource, root, root != null); } public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) { final Resources res = getContext().getResources(); if (DEBUG) { Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" (" + Integer.toHexString(resource) + ")"); } //根据layoutId获取xml解析器 final XmlResourceParser parser = res.getLayout(resource); try { //将xml解析器和ViewGroup容器、是否加载到根节点下传入 inflate方法中 return inflate(parser, root, attachToRoot); } finally { parser.close(); } } public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) { synchronized (mConstructorArgs) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate"); final Context inflaterContext = mContext; final AttributeSet attrs = Xml.asAttributeSet(parser); //获取属性 Context lastContext = (Context) mConstructorArgs[0]; mConstructorArgs[0] = inflaterContext; View result = root; //把(contentPerent)ViewGroup赋值给result try { // Look for the root node. 寻找根节点 int type; while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) { // Empty } if (type != XmlPullParser.START_TAG) { throw new InflateException(parser.getPositionDescription() + ": No start tag found!"); } final String name = parser.getName(); if (DEBUG) { System.out.println("**************************"); System.out.println("Creating root view: " + name); System.out.println("**************************"); } if (TAG_MERGE.equals(name)) {//判断根节点是否为merge标签 if (root == null || !attachToRoot) {//判断root是否为空,merge必须添加到ViewGroup里 throw new InflateException("<merge /> can be used only with a valid " + "ViewGroup root and attachToRoot=true"); } rInflate(parser, root, inflaterContext, attrs, false); } else {//当根节点不是merge标签时 // Temp is the root view that was found in the xml final View temp = createViewFromTag(root, name, inflaterContext, attrs);//生成根节点 ViewGroup.LayoutParams params = null; if (root != null) { if (DEBUG) { System.out.println("Creating params from root: " + root); } // Create layout params that match root, if supplied params = root.generateLayoutParams(attrs);//调用content的FrameLayout的属性解析 if (!attachToRoot) { // Set the layout params for temp if we are not // attaching. (If we are, we use addView, below) temp.setLayoutParams(params);//添加属性到已创建的根节点上 } } if (DEBUG) { System.out.println("-----> start inflating children"); } // Inflate all children under temp against its context. rInflateChildren(parser, temp, attrs, true);//解析根节点下的子节点 if (DEBUG) { System.out.println("-----> done inflating children"); } // We are supposed to attach all the views we found (int temp) // to root. Do that now. if (root != null && attachToRoot) { root.addView(temp, params); } // Decide whether to return the root that was passed in or the // top view found in xml. if (root == null || !attachToRoot) { result = temp; } } } catch (XmlPullParserException e) { InflateException ex = new InflateException(e.getMessage()); ex.initCause(e); throw ex; } catch (Exception e) { InflateException ex = new InflateException( parser.getPositionDescription() + ": " + e.getMessage()); ex.initCause(e); throw ex; } finally { // Don't retain static reference on context. mConstructorArgs[0] = lastContext; mConstructorArgs[1] = null; } Trace.traceEnd(Trace.TRACE_TAG_VIEW); return result; } } final void rInflateChildren(XmlPullParser parser, View parent, AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException { rInflate(parser, parent, parent.getContext(), attrs, finishInflate); } /** * Recursive method used to descend down the xml hierarchy and instantiate * views, instantiate their children, and then call onFinishInflate(). * <p> * <strong>Note:</strong> Default visibility so the BridgeInflater can * override it. */ void rInflate(XmlPullParser parser, View parent, Context context, AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException { final int depth = parser.getDepth(); int type; while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { continue; } final String name = parser.getName(); if (TAG_REQUEST_FOCUS.equals(name)) { parseRequestFocus(parser, parent); } else if (TAG_TAG.equals(name)) { parseViewTag(parser, parent, attrs); } else if (TAG_INCLUDE.equals(name)) {//如果标签名为include if (parser.getDepth() == 0) { throw new InflateException("<include /> cannot be the root element");//include 标签不能作为根节点 } parseInclude(parser, context, parent, attrs); } else if (TAG_MERGE.equals(name)) {//如果标签名为merge throw new InflateException("<merge /> must be the root element"); //merge标签只能作为根节点 //merge标签加载后会减少节点层级 } else {//如果根节点不存在,创建根节点,遍历子节点 final View view = createViewFromTag(parent, name, context, attrs); final ViewGroup viewGroup = (ViewGroup) parent; final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs); rInflateChildren(parser, view, attrs, true); viewGroup.addView(view, params); } } //解析merge标签时finishInflate为true if (finishInflate) { parent.onFinishInflate();} }
LayoutInflater解析的过程图,通过深度优先遍历:
0 0
- LayoutInflater 到底怎么把xml添加到decorview
- LayoutInflater 是怎么把xml添加到decorview?
- DecorView如何添加到Window
- 怎么把UltraEdit添加到右键菜单
- DecorView如何添加到Window上
- 怎么把maven工程的包添加到tomcat上
- xcode怎么把自定义代码添加到代码库CodeSnippets
- 怎么把XML文件导入到csdn博客啊?
- 顶层视图DecorView添加到窗口的过程
- 该怎么把这个“JiaThis分享到按钮”添加到5D6D论坛呢?
- 大家好,我想在这个网站下一个东西,我不知道到底要怎么才能把资料填到100%
- 怎么把同一数据源里的数据添加到不同的listView里面
- 怎么把注册信息一下子添加到3个数据库的表中
- XML文件怎么添加注释
- 把程序添加到开始菜单
- 用editplus编辑PHP,每次新键时,要到“others...”中才有PHP,怎么把PHP添加到新建中
- 怎么把QLabel添加进QGraphicsItem
- 怎么把xml文件转为java文件
- TI的CCS的一个编译错误
- maven插件之maven-javadoc-plugin
- draw9patch使用问题
- JavaScript对象——对象属性
- 线程同步
- LayoutInflater 到底怎么把xml添加到decorview
- Linux 定时任务Crontab
- 朋友(特长生准备)
- maven插件之maven-source-plugin
- JavaScript类型检测
- 【C#】S.O.L.I.D
- JavaScript对象——对象的继承
- Java基础类库
- Jstl中<c:out>标签的使用