LayoutInflater 的使用方式:
方式一:
方式二:
方式三:
三种方式效果一样,返回View对象
参数的作用
- resource:Int
需要加载的XML布局资源的ID - root:ViewGroup
指定一个父View - attachToRoot:boolean
是否添加到root中
很明显,主要的决定条件就是root:ViewGroup,attachToRoot:boolean这两个参数:
- attachToRoot:boolean为空,则默认为true
- root不为null,attachToRoot设为false,此时root会协助需要加载的XML布局资源进行根节点的layout属性进行设值,但不会加载进root下
- root不为null,attachToRoot设为true,即将需要加载的XML布局资源添加到root中
- 当root为null,attachToRoot将失去作用,即不添加到root中,此时需要加载的XML布局资源的根节点的layout属性是没有的,如果我们将该布局添加到某一个容器中,怎么在该布局的根节点进行设置宽高都是没有效果的,但是在根节点的子控件设值却可以改变布局宽高,这是因为子控件是有父布局的呀。
源码
进入inflate():
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) + \")\");}//检查是否有预编译,如果有直接使用View view = tryInflatePrecompiled(resource, res, root, attachToRoot);if (view != null) {return view;}//解析xml文件得到XmlResourceParser对象XmlResourceParser parser = res.getLayout(resource);try {//调用重载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;try {//判断布局的合理性advanceToRootNode(parser);final String name = parser.getName();if (DEBUG) {System.out.println(\"**************************\");System.out.println(\"Creating root view: \"+ name);System.out.println(\"**************************\");}//如果根节点是Merge标签if (TAG_MERGE.equals(name)) {//root必须不为空,且attachToRoot为true,//也就是必须添加到root中,不然报异常if (root == null || !attachToRoot) {throw new InflateException(\"<merge /> can be used only with a valid \"+ \"ViewGroup root and attachToRoot=true\");}//调用rInflate()方法解析rInflate(parser, root, inflaterContext, attrs, false);} else {//根据节点名来创建View对象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);}//root != null则根据当前标签生成LayoutParamsparams = root.generateLayoutParams(attrs);if (!attachToRoot) {//如果attachToRoot==false,则把LayoutParams信息设值到根节点上temp.setLayoutParams(params);}}if (DEBUG) {System.out.println(\"-----> start inflating children\");}//调用rInflateChildren()rInflateChildren(parser, temp, attrs, true);if (DEBUG) {System.out.println(\"-----> done inflating children\");}if (root != null && attachToRoot) {//如果Root不为null且是attachToRoot==true,则添加创建出来的View到root中,同时把params设置上去root.addView(temp, params);}if (root == null || !attachToRoot) {result = temp;}}} catch (XmlPullParserException e) {final InflateException ie = new InflateException(e.getMessage(), e);ie.setStackTrace(EMPTY_STACK_TRACE);throw ie;} catch (Exception e) {final InflateException ie = new InflateException(getParserStateDescription(inflaterContext, attrs)+ \": \" + e.getMessage(), e);ie.setStackTrace(EMPTY_STACK_TRACE);throw ie;} finally {// Don\'t retain static reference on context.mConstructorArgs[0] = lastContext;mConstructorArgs[1] = null;Trace.traceEnd(Trace.TRACE_TAG_VIEW);}return result;}}