Android的Inflater使用
发布日期:2021-05-10 06:29:16 浏览次数:28 分类:原创文章

本文共 4590 字,大约阅读时间需要 15 分钟。

LayoutInflater 的使用方式:

方式一:
在这里插入图片描述
方式二:
在这里插入图片描述
方式三:
在这里插入图片描述
三种方式效果一样,返回View对象

参数的作用

  1. resource:Int
    需要加载的XML布局资源的ID
  2. root:ViewGroup
    指定一个父View
  3. 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则根据当前标签生成LayoutParams                    params = 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;    }}
上一篇:ListView使用以及乱序问题如何解决
下一篇:Android的广播接收者

发表评论

最新留言

很好
[***.229.124.182]2025年04月26日 19时04分31秒