美文网首页
Android LayoutInflater

Android LayoutInflater

作者: Android_冯星 | 来源:发表于2019-01-18 16:19 被阅读0次

    参考文章

    Android LayoutInflater原理分析,带你一步步深入了解View(一)

    Android LayoutInflater源码解析

    请直接观看上面的文章。下面的可以不必看。

    记录

    LayoutInflater 的作用就是将XML布局文件实例化为相应的 View 对象

    总结

    1. LayoutInflater的内部实现方式,主要是pull解析布局文件
    2. attachToRoot参数作用
    • root != null, attachToRoot == true
      传进来的布局会被加载成为一个View并作为子View添加到root中,最终返回root;
      而且这个布局根节点的android:layout_xxx参数会被解析用来设置View的大小;

    • root == null, attachToRoot无意义
      当root为空时,attachToRoot无论是什么都没有意义。此时传进来的布局会被加载成为一个View并直接返回;
      布局根View的android:layout_xxx属性会被忽略,即android:layout_xx属性只有依附在某个ViewGroup中才能生效;

    • root != null, attachToRoot == false
      传进来的布局会被加载成为一个View并直接返回。
      布局根View的android:layout_xxx属性会被解析成LayoutParams并设置在View上,此时root只用于设置布局根View的大小和位置。

    1. 通过标签以反射的方式来创建 View 对象;

    2. 加载xml布局的原理
      其实就是从根节点开始,递归解析xml的每个节点,每一步递归的过程是:通过节点名称(全类名),使用ClassLoader创建对应类的实例,也就是View,然后,将这个View添加到它的上层节点(父View)。并同时会解析对应xml节点的属性作为View的属性。每个层级的节点都会被生成一个个的View,并根据View的层级关系add到对应的直接父View(上层节点)中,最终返回一个包含了所有解析好的子View的布局根View。

    为什么view嵌套view多了会造成卡顿?

    public void setContentView(int resId) {
            this.ensureSubDecor();
            ViewGroup contentParent = (ViewGroup)this.mSubDecor.findViewById(16908290);
            contentParent.removeAllViews();
            LayoutInflater.from(this.mContext).inflate(resId, contentParent);
            this.mOriginalWindowCallback.onContentChanged();
        }
    

    setContentView方式内部也是使用LayoutInflater把布局加入到FrameLayout布局中的,而根据上面两篇文章,说到

     void rInflate(XmlPullParser parser, View parent, Context context,
                AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException {
    
            final int depth = parser.getDepth();
            int type;
            boolean pendingRequestFocus = false;
    
            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)) {
                    pendingRequestFocus = true;
                    consumeChildElements(parser);
                } else if (TAG_TAG.equals(name)) {
                    parseViewTag(parser, parent, attrs);
                } else if (TAG_INCLUDE.equals(name)) {
                    if (parser.getDepth() == 0) {
                        throw new InflateException("<include /> cannot be the root element");
                    }
                    parseInclude(parser, context, parent, attrs);
                } else if (TAG_MERGE.equals(name)) {
                    throw new InflateException("<merge /> must be the root element");
                } 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);
                }
            }
    
            if (pendingRequestFocus) {
                parent.restoreDefaultFocus();
            }
    
            if (finishInflate) {
                parent.onFinishInflate();
            }
        }
    

    这个方式使用了递归算法,在这里

    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);
                }
    

    如果嵌套层次过多,是会造成显示过慢。
    当然使用LayoutInflater只是卡顿众多原因的一个,还有View的测量和绘制都是递归实现的。

    递归调用效率问题,递归与循环比较

    相关文章

      网友评论

          本文标题:Android LayoutInflater

          本文链接:https://www.haomeiwen.com/subject/sqvndqtx.html