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给出了四个方法
notion image
可以发现最终这些方法都会调用第三个方法,所以我们只需要关注这个方法。其中,重要的部分可以概括如下
这段代码首先用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)

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

inflate(resource, root)

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

inflate(resource, root, false)

notion image
输出信息如下: 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等属性仍然有效;
  1. 如果root为null,attachToRoot将没有意义,此时返回xml的根节点。且该根节点设置任何layout参数都没有意义。这很好理解,因为layout参数是描述自身在父控件或者容器下的属性,这时候没有容器,当然就失效了。
  1. 如果root不为null,attachToRoot设为true,则会给resource指定一个父布局root,即执行root.addView(resource, params),然后返回root,且root的layout参数会保留。
  1. 如果root不为null,attachToRoot设为false,则会将root最外层的layout属性设置为resource最外层的layout属性,即执行resource.setLayoutParams(params),然后返回resource。相当于root只提供布局参数。
  1. 如果可以传递root的情况下,就选择传递root;避免传入null,否则layout参数会失效。
Loading...

© 刘口子 2018-2025