为什么LayoutInflater.inflate方法会返回作为参数传递的根视图?

10

我尝试在代码中将一个视图放入容器中,并同时获取到我所充气的视图(一个按钮)的引用。因此,代码如下:

Button mybut = (Button) getLayoutInflater().inflate(resID, lyMain, true);

但是这并不起作用:返回的结果不是我期望的。在 https://developer.android.com/reference/android/view/LayoutInflater.html 上阅读文档后,我发现:

(inflate...returns)...被填充层次结构的根视图。如果提供了root并且attachToRoot为true,则这是root;否则它是填充的XML文件的根。

现在是一个愚蠢的问题:为什么该方法应该返回我已经知道的内容(当我将根和“true”传递给它时)?更有可能我需要对刚刚被填充的视图进行引用,而不是传递给方法的根/容器。

2个回答

6

确实有点奇怪。但是按照以下方法操作将得到完全相同的结果,而且可以捕获充气布局:

Button mybut = (Button) getLayoutInflater().inflate(resID, lyMain, false);
lyMain.addView(mybut);

所以,需要额外编写一行代码,但与调用findViewByIdgetView(index)相比,这似乎只是一个小不便。
文档已经很好地解释了区别,但我想你已经阅读过了:

root: 可选视图,用于作为生成的层次结构的父级(如果attachToRoot为true),否则仅是提供一组LayoutParams值以用于返回层次结构的根元素的对象(如果attachToRoot为false)。


1
是的,我阅读了文档,也按照你说的做了——用两个语句。我之所以问是因为我想确保这个“奇怪”的返回值:它可能允许一些我不知道的其他结构。 - linuxfan says Reinstate Monica
我认为@natario的解释很可能是它实际发生的原因。 - code_mc

3
我认为这种设计选择的原因是你的布局资源本身可能没有根节点。这就是例如布局的情况。
<merge>
    <View />
    <Button />
</merge>

这个视图可以在父ViewGroup中展开,但不能用单个View实例来表示整个视图。在这里,返回父ViewGroup似乎是唯一的选择。


实际上我使用了merge,可以看看我的问题和回答:http://stackoverflow.com/questions/41302370/android-how-to-recreate-same-button-view-in-another-activity 我会尝试传递root和_false_到inflate()函数。 - linuxfan says Reinstate Monica
我认为它会抛出异常。 <merge> 标记可以包含多个子项。你期望获取哪个子项?请看我的例子。没有理由它应该返回 Button。 - natario
真的。但这毫无意义。在我的情况下只有一个按钮,而且错误出现在“mybut = ...inflate(..., group, false)”上。错误是“merge can only be used with root and attach=true”。inflate()需要一个根视图,然后想将新视图附加到根视图,然后拒绝给我一个引用。所以我找到的唯一方法就是你在帖子中看到的那个,我觉得它很丑陋。 - linuxfan says Reinstate Monica
@linuxfan,嗯,使用只有一个子元素的<merge>标签也是毫无意义的。我建议你多了解一下这个标签,因为使用<merge><Button></merge>与仅使用<Button>完全相同。唯一的区别是,如果你使用<Button>,你就不会遇到在这里描述的问题。 - natario
在我的第一次尝试中,我没有使用合并,但是Android Studio设计编辑器出现了问题,而且似乎是必要的。现在我已经删除了它,实际上它可以工作。设计师仍然不满意,但是“可行”。关于inflate()返回的引用,我认为返回第一个膨胀的视图比返回我已经拥有的东西更明智,特别是当文档说它可以返回对膨胀视图的引用时。假设通常情况下,我知道我要膨胀什么!谢谢和问候。 - linuxfan says Reinstate Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接