Android LayoutInflater.inflate方法的参数解析
status
category
date
summary
slug
icon
tags
password
发现一个小问题
项目中需要加载xml文件时,经常使用下面这个方法 (其实View.inflate,setContentView内部都是用LayoutInflater实现的)
View view = LayoutInfalter.from(this).inflate(**.xml, null);
其中第二个root参数显示为@Nullable,但是实际上传入null时,又会飘黄警告:
Avoid passing null as the view root (needed to resolve layout parameters on the inflated layout’s root element) less… (Ctrl+F1) When inflating a layout, avoid passing in null as the parent view, since otherwise any layout parameters on the root of the inflated layout will be ignored. 避免将null作为root参数传入该方法(因为传入null会使根部局的layout参数失效)
接下来就学习一下这个警告是什么意思
源码分析
Android官方API给出了四个方法

可以发现最终这些方法都会调用第三个方法,所以我们只需要关注这个方法。其中,重要的部分可以概括如下
这段代码首先用result获取了可能存在的父视图,如果root为null,result就向下返回当前view;如果root不为null,就把当前view添加到ViewGroup中,最终形成一个DOM结构,最后把DOM树最顶层的根部局返回。
总结得到了以下结论: 1. 如果root为null,attachToRoot将失去作用; 2. 如果root不为null,attachToRoot为true,则会将当前view添加到父view中; 3. 如果root不为null,attachToRoot为false,则会将布局文件最外层的所有layout属性进行设置,当该view被添加到父view的时候,父view的最外层layout属性将会改为子view的layout属性;
实例验证
首先定义parent.xml为父视图:
child.xml为子视图:
inflate(resource, null)
运行结果:

Logcat中没有任何输出信息,表明inflate前后的layout属性均为null 这是因为resource外层没有root,导致layout属性失效,因此默认match_parent; ***
inflate(resource, root)
运行结果:

Logcat中同样没有任何输出信息,这说明inflate(resource, root)和inflate(resource, root, true)只是将resource加到了root之下,并没有改变最外层的layout属性。 ***
inflate(resource, root, false)

输出信息如下: 2018-11-17 17:28:54.567 4036-4036/com.rimson.c.inflatepractice D/MainActivity: after:600 2018-11-17 17:28:54.567 4036-4036/com.rimson.c.inflatepractice D/MainActivity: after:1200
说明infalte执行后,把子view的layout参数赋给了父view。 ***
总结
- root是给当前要填充的resource外层再加上的一层ViewGroup;
- 在不设置attachToRoot参数的情况下,这一参数的取值默认为(root != null);
- layout参数指的是layout_xxx,例如background等属性仍然有效;
- 如果root为null,attachToRoot将没有意义,此时返回xml的根节点。且该根节点设置任何layout参数都没有意义。这很好理解,因为layout参数是描述自身在父控件或者容器下的属性,这时候没有容器,当然就失效了。
- 如果root不为null,attachToRoot设为true,则会给resource指定一个父布局root,即执行root.addView(resource, params),然后返回root,且root的layout参数会保留。
- 如果root不为null,attachToRoot设为false,则会将root最外层的layout属性设置为resource最外层的layout属性,即执行resource.setLayoutParams(params),然后返回resource。相当于root只提供布局参数。
- 如果可以传递root的情况下,就选择传递root;避免传入null,否则layout参数会失效。
Loading...