LayoutInflater.inflater()参数解释

本文介绍了LayoutInflater.inflate()方法的作用,区分了它与findViewById的区别。详细解析了inflate()的四个重载方法,特别是参数的意义:resouce用于初始化视图,root提供父布局,attachToRoot决定是否将视图添加到父布局。在Adapter的getView中,不正确使用可能导致item布局尺寸问题。建议使用inflate(resouce, root, false)避免问题。" 8623137,1384625,PHP内核中的哈希表详解,"['PHP内核', '数据结构', '哈希表', '数组实现', '冲突解决策略']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LayoutInflater.inflater()方法就是根据一个xml文件来生成一个view对象,注意跟getviewbyid的区别,后者是从view独享中找到指定的控件。

在LayoutInflater中对inflater()有四种重载分别是

  1. public View inflate(int, ViewGroup)
  2. public View inflate(XmlPullParser, ViewGroup)
  3. public View inflate(int, ViewGroup, boolean)
  4. public View inflate(XmlPullParser, ViewGroup, boolean)

好的,老规矩上源码,不用看懂,哥们后面会帮你简化的,

 public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
        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) + ")");
        }

        final XmlResourceParser parser = res.getLayout(resource);
        try {
            return inflate(parser, root, attachToRoot);
        } finally {
            parser.close();
        }
    }

得到的答案是根据resource初始化视图后调用4号方法

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 {
                // 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)) {
                    if (root == null || !attachToRoot) {
                        throw new InflateException("<merge /> can be used only with a valid "
                                + "ViewGroup root and attachToRoot=true");
                    }

                    rInflate(parser, root, inflaterContext, attrs, false);
                } else {
                    // 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);
                        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) {
                final InflateException ie = new InflateException(e.getMessage(), e);
                ie.setStackTrace(EMPTY_STACK_TRACE);
                throw ie;
            } catch (Exception e) {
                final InflateException ie = new InflateException(parser.getPositionDescription()
                        + ": " + 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;
        }
    }




眼疼不?疼的话咱们看简化版本的

public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {  
    synchronized (mConstructorArgs) {  
        //第一步:初始化  
        final AttributeSet attrs = Xml.asAttributeSet(parser);  
        Context lastContext = (Context)mConstructorArgs[0];  
        mConstructorArgs[0] = mContext;  
        //注意这里,在初始化时,result表示要返回的视图,默认是返回root  
        View result = root;  

        …………  

        final String name = parser.getName();  

        //第二步:创建XML对应的空白VIEW:temp  
        if (TAG_MERGE.equals(name)) {  
        //如果是merge标签:抛出异常  (因为merge标签能够将该标签中的所有控件直接连在上一级布局上面,从而减少布局层级,假如一个线性布局替换为merge标签,那么原线性布局下的多个控件将直接连在上一层结构上,也就是如果加载进来的root根节点是root的话,那么将来无法知道布局的根节点是什么)
            …………  
        } else {  
            View temp;  
            if (TAG_1995.equals(name)) {  
                temp = new BlinkLayout(mContext, attrs);  
            } else {  
                temp = createViewFromTag(root, name, attrs);  
            }  

            //第三步:从根结点中,获取布局参数,设置到temp中  
            ViewGroup.LayoutParams params = null;  
            if (root != null) {  
                // Create layout params that match root, if supplied  
                params = root.generateLayoutParams(attrs);  
                if (!attachToRoot) {  
                    // Set the layout params for temp if we are not  
                    // attaching. (If we are, we use addView, below)  
                    temp.setLayoutParams(params);  
                }  
            }  

            //第四步:初始化temp中的子控件  
            rInflate(parser, temp, attrs, true);  

            //第五步:如果root不为空,而且attachToRoot设为TRUE,则将其视图通过addView添加到root中  
            if (root != null && attachToRoot) {  
                root.addView(temp, params);  
            }  

            //第六步:如果root为空,或者attachToRoot设为FALSE,那么就将TEMP视图做为result返回  
            if (root == null || !attachToRoot) {  
                result = temp;  
            }  
        }  

        return result;  
    }  
} 

看到这里咱们就可以进入正题了 每个参数是社么意思?

public View inflate(int resouce, ViewGroup root, boolean attachToRoot)

  • 第一个参数 生成temp,注意这里的temp不一定是inflate这个方法返回的view奥
  • root 父布局 为temp提供参数,如果没有temp默认是wrap_content
  • attachToRoot是否调用addview添加到父布局

    使用过程中出现的问题总结


    总结一下adapter的getview中出现的问题
    一,在item根布局中,明明定义了match或者200dp,但是item还是wrap_content,
    看看你调用的是不是nflate(resouce, null)’因为这里没有传入父布局所以无法为temp添加跟节点所需要的参数,(不添加参数怎么了?老子定义了match了!),您定义的在初始化temp的时候系统没加进去,谢谢
    正确的方法是nflate(resouce, root,false)
    (老子就不,你让我false 我就弄个true)
    true的意思基本和
    listview。add(item);
    然后把listview返回差不多
    报错没有 这里的root相当于是listview 你listview。add(item)不出错吗?
    为什么我nflate(resouce, null)出来的额itemview也正常呢
    因为你的itemview中的子控件已经把它给撑大了,
  • -
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值