LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot)方法解析

main布局:
<? xml version= "1.0"  encoding= "utf-8" ?>
<LinearLayout  xmlns: android = "http://schemas.android.com/apk/res/android"
     android :id= "@+id/layoutContent"
     android :layout_width= "match_parent"
     android :layout_height= "match_parent"
     android :orientation= "vertical" >
</LinearLayout>

待加载布局文件:
<? xml version= "1.0"  encoding= "utf-8" ?>
<RelativeLayout  xmlns: android = "http://schemas.android.com/apk/res/android"
     android :id= "@+id/layout1"
     android :layout_width= "200dp"
     android :layout_height= "300dp"
     android :background= "@color/Color_D" >

    <Button
         android :layout_width= "wrap_content"
         android :layout_height= "wrap_content"
         android :text= "100"
         android :layout_centerInParent= "true" />

</RelativeLayout>

1、inflate(resource, null):

代码:
@Override
protected void  onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState) ;
    setContentView(R.layout. activity_main) ;
    LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
    View view = LayoutInflater. from( this).inflate(R.layout. layout1 , null) ;
    layoutContent.addView(view) ;
}

结果:
待加载布局文件中layout_width、layout_height参数不起作用

2、inflate(resource, root,true):
将上述java代码改为:
@Override
protected void  onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState) ;
    setContentView(R.layout. activity_main) ;
    LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
    View view = LayoutInflater. from( this).inflate(R.layout. layout1 layoutContent , true) ;
    layoutContent.addView(view) ;
}

运行,程序崩溃。

再次将代码改为如下形式:
@Override
protected void  onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState) ;
    setContentView(R.layout. activity_main) ;
    LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
    View view = LayoutInflater. from( this).inflate(R.layout. layout1 layoutContent , true) ;
}

程序成功运行,且带加载布局文件中的layout_width、layout_height参数有效。

3、inflate(resource, root, false):
将上述java代码改为:
@Override
protected void  onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState) ;
    setContentView(R.layout. activity_main) ;
    LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
    View view = LayoutInflater. from( this).inflate(R.layout. layout1 layoutContent , false) ;
}

程序可正常运行,但不显示待加载View

再次将上述java代码改为:
@Override
protected void  onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState) ;
    setContentView(R.layout. activity_main) ;
    LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
    View view = LayoutInflater. from( this).inflate(R.layout. layout1 layoutContent , false) ;
    layoutContent.addView(view) ;
}

程序正常运行,且待加载布局文件中的layout_width、layout_height有效。

4、inflate(resource, null,false):
将上述java代码改为:
@Override
protected void  onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState) ;
    setContentView(R.layout. activity_main) ;
    LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
    View view = LayoutInflater. from( this).inflate(R.layout. layout1 , null, false) ;
    layoutContent.addView(view) ;
}

程序正常运行,但待加载布局文件中的layout_width、layout_height不起作用

5、inflate(resource, null, true):
将上述java代码改为:
@Override
protected void  onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState) ;
    setContentView(R.layout. activity_main) ;
    LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
    View view = LayoutInflater. from( this).inflate(R.layout. layout1 , null, true) ;
    layoutContent.addView(view) ;
}

程序正常运行,但待加载布局文件中的layout_width、layout_height不起作用

再次将上述java代码改为:
@Override
protected void  onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState) ;
    setContentView(R.layout. activity_main) ;
    LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
    View view = LayoutInflater. from( this).inflate(R.layout. layout1 , null, true) ;
}

程序正常运行,不显示待加载view


inflate()方法源码分析:
public View  inflate(XmlPullParser parser ViewGroup root , boolean attachToRoot) {
     synchronized ( mConstructorArgs) {
        Trace.traceBegin(Trace.TRACE_TAG_VIEW "inflate") ;

        final AttributeSet attrs = Xml. asAttributeSet(parser) ;
        Context lastContext = (Context) mConstructorArgs[ 0] ;
         mConstructorArgs[ 0] =  mContext ;
        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 attrs , false, false) ;
            else {
                 // Temp is the root view that was found in the xml
                 final View temp = createViewFromTag(root name attrs , false) ;

                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
                rInflate(parser temp attrs , true, 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) {
            InflateException ex =  new InflateException(e.getMessage()) ;
            ex.initCause(e) ;
            throw ex ;
        catch (IOException e) {
            InflateException ex =  new InflateException(
                    parser.getPositionDescription()
                    +  ": " + e.getMessage()) ;
            ex.initCause(e) ;
            throw ex ;
        finally {
             // Don't retain static reference on context.
             mConstructorArgs[ 0] = lastContext ;
             mConstructorArgs[ 1] =  null;
        }

        Trace.traceEnd(Trace.TRACE_TAG_VIEW) ;

        return result ;
    }
}

一、 如果root != null:

  1、如果attachToRoot == false:
       
// 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) ;
}
// Inflate all children under temp
rInflate(parser temp attrs , true, true) ;

如代码所示,此时根据root生成layout param,然后将其应用于生成的view,接着递归inflate View的子View,由下面二中的分析可知,最终返回该view。

  2、如果attachToRoot == true:
从代码可以看出,此时同样为View设置layoutParam,然后直接将其添加到root中:
if (root !=  null && attachToRoot) {
    root.addView(temp params) ;
}

由于一开始将result设置为root,可知,最终返回的为root,这也解释了,为什么在root !=null且attachToRoot为true时,调用addView()方法会导致崩溃,也就是前面实验2的情况。

二、如果root == null 或者 attachToRoot为false:
if (root ==  null || !attachToRoot) {
    result = temp ;
}

由代码可知,此时既不为View设置layoutParams,也不将其添加到root中,由于最终返回result,因此最终将其直接返回。

总结一下:
1、root != null && attachToRoot == false:
根据root为View设置layoutParams,不将该View添加到root上,最终返回该View。
2、root != null && attachToRoot == true:
根据root为View设置layoutParams,接着将该view添加到root上,最终返回root。
3、root == null 
不根据root为View设置layoutParams,不将该view添加到root上,最终返回该view。
由代码可以看出,当root == null时,attachToRoot参数无效。

可以看到,最终的结论跟前面的实验结果是相匹配的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值