LayoutInflater inflate()方法参数解析

LayoutInflater的使用有下面4种方法:

  1. LayoutInflater.from(this).inflate(R.layout.xxx, null)
  2. LayoutInflater.from(this).inflate(R.layout.xxx, parent)
  3. LayoutInflater.from(this).inflate(R.layout.xxx, parent,true)
  4. LayoutInflater.from(this).inflate(R.layout.xxx, parent,false)

点进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;
        }
        XmlResourceParser parser = res.getLayout(resource);
        try {
            return inflate(parser, root, attachToRoot);
        } finally {
            parser.close();
        }
    }

 两个参数的方法最终也调用了上面三个参数的方法

 public View inflate(XmlPullParser parser, @Nullable ViewGroup root) {
        return inflate(parser, root, root != null);
    }

会发现:使用方法2=使用方法3

最终调用带解析器的inflate方法
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 {
                //省略了一些判断等代码 重点是下面这段代码
                   ......
         //1.获取xml解析器的名字
                    final String name = parser.getName();
                    // Temp is the root view that was found in the xml
        //2.用动态反射的方法把name创建成View,这个temp就是xml最外层的rootview,
        //  但是这个创建出来的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);
                        }
                        // Create layout params that match root, if supplied
                        params = root.generateLayoutParams(attrs);

         //3.如果parent传入的不是null 并且attachToRoot =false 就给temp设置属性,最后会返回temp
                        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.
            //4.如果parent传的不是null 并且attachToRoot =true,就把xml和属性添加到 parent中
                    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.
            //5.  如果parent传的是null或者attachToRoot==false,则把xml反射创建出来,不设置属性返回
                    if (root == null || !attachToRoot) {
                        result = temp;
                    }
               ......

            return result;
        }
    }

总结:

  1. parent 传空,即:第二个参数是null ,就把xml动态创建成View ,不设置属性(宽高,边距等),然后返回View
  2. LayoutInflater.from(this).inflate(R.layout.xxx, parent)等同于LayoutInflater.from(this).inflate(R.layout.xxx, parent,true)
    把xml创建成view,设置属性并添加到parent中,然后返回parent,注意这里是把xml 添加到parent里,return的是parent!
  3. LayoutInflater.from(this).inflate(R.layout.xxx, parent,false)
    把xml创建成view并设置了属性,然后返回view

你可能感兴趣的:(LayoutInflater inflate()方法参数解析)