LayoutInflater。膨胀文档对我来说并不完全清楚attachtorroot参数的用途。

attachtorroot:膨胀的层次结构是否应该附加到根参数?如果为false,则root仅用于创建正确的 XML中根视图的LayoutParams的子类。

有没有人能更详细地解释一下,具体地说,根视图是什么,也许还能举个例子,说明在真值和假值之间的行为变化?


当前回答

文档和之前的两个答案应该足够了,只是我的一些想法。

充气方法用于充气布局文件。有了这些膨胀的布局,你就有可能直接将它们附加到父ViewGroup上,或者只是从那个布局文件中膨胀视图层次结构,并在正常的视图层次结构之外使用它。

在第一种情况下,attachtorroot参数必须设置为true(或者简单地使用膨胀方法,它接受一个布局文件和一个父根ViewGroup(非空))。在这种情况下,返回的视图只是在方法中传递的ViewGroup,膨胀的视图层次结构将添加到该ViewGroup。

For the second option the returned View is the root ViewGroup from the layout file. If you remember our last discussion from the include-merge pair question this is one of the reasons for the merge's limitation(when a layout file with merge as root is inflated, you must supply a parent and attachedToRoot must be set to true). If you had a layout file with the root a merge tag and attachedToRoot was set to false then the inflate method will have nothing to return as merge doesn't have an equivalent. Also, as the documentation says, the inflate version with attachToRoot set to false is important because you can create the view hierarchy with the correct LayoutParams from the parent. This is important in some cases, most notable with the children of AdapterView, a subclass of ViewGroup, for which the addView() methods set is not supported. I'm sure you recall using this line in the getView() method:

convertView = inflater.inflate(R.layout.row_layout, parent, false);

这一行确保了膨胀的R.layout。row_layout文件在它的根ViewGroup上设置了来自AdapterView子类的正确LayoutParams。如果你不这样做,你可能会有一些问题与布局文件,如果根是RelativeLayout。tableelayout /TableRow也有一些特殊和重要的LayoutParams,你应该确保它们中的视图有正确的LayoutParams。

其他回答

当你定义父对象时,attachtorroot决定你是否想要膨胀器把它附加到父对象上。在某些情况下,这会导致问题,比如在ListAdapter中,它会导致一个异常,因为列表试图将视图添加到列表中,但它说它已经附加。在其他情况下,您只是自己膨胀视图以添加到活动,这可能很方便,并节省了一行代码。

如果设置为true,那么当你的布局膨胀时,它将自动添加到ViewGroup的视图层次结构中,在第二个参数中指定作为子参数。例如,如果根参数是线性布局,那么你的膨胀视图将自动添加为该视图的子视图。

如果它被设置为false,那么你的布局将被膨胀,但不会附加到任何其他布局(所以它不会被绘制,接收触摸事件等)。

我自己也很困惑膨胀方法中attachtorroot的真正目的是什么。在研究了一些UI后,我终于得到了答案:

家长:

在本例中是围绕视图对象的小部件/布局,您希望使用findViewById()进行膨胀。

attachToRoot:

将视图附加到它们的父视图(将它们包含在父层次结构中),因此视图接收到的任何触摸事件也将被转移到父视图。现在,由父母决定是要接受这些事件还是忽略它们。如果设置为false,它们不会作为父节点的直接子节点被添加,父节点也不会从视图中接收任何触摸事件。

希望这能澄清困惑

回复中似乎有很多文本,但没有代码,这就是为什么我决定用一个代码示例来恢复这个老问题,在几个回复中人们提到:

如果设置为true,那么当你的布局膨胀时,它将自动添加到ViewGroup的视图层次结构中,在第二个参数中指定作为子参数。

这在代码中的实际含义(大多数程序员都能理解)是:

public class MyCustomLayout extends LinearLayout {
    public MyCustomLayout(Context context) {
        super(context);
        // Inflate the view from the layout resource and pass it as child of mine (Notice I'm a LinearLayout class).

        LayoutInflater.from(context).inflate(R.layout.child_view, this, true);
    }
}

注意,前面的代码添加了布局R.layout。child_view作为MyCustomLayout的孩子,因为attachToRoot参数为真,并以完全相同的方式分配父布局参数,如果我将使用addView编程,或如果我在xml中这样做:

LinearLayout < > <视图…/ > ... LinearLayout < / >

下面的代码解释了当传递attachRoot为false时的场景:

LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setLayoutParams(new LayoutParams(
    LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
linearLayout.setOrientation(LinearLayout.VERTICAL);
    // Create a stand-alone view
View myView = LayoutInflater.from(context)
    .inflate(R.layout.ownRootView, null, false);
linearLayout.addView(myView);

在前面的代码中,你指定你想要myView是它自己的根对象,不附加到任何父对象,后来我们将它添加为LinearLayout的一部分,但暂时它是一个独立的(没有父)视图。

同样的事情也发生在Fragments上,你可以将它们添加到一个已经存在的组中并成为它的一部分,或者只是传递参数:

inflater. inflation (r.b ayout.fragment, null, false);

来指定它将是它自己的根。

只是分享一些我在研究这个话题时遇到的问题,

除了公认的答案,我想提出一些可能会有所帮助的观点。

所以,当我使用attachtorroot为true时,返回的视图类型为ViewGroup,即父的根ViewGroup,它作为参数传递给了填充(layoutResource,ViewGroup, attachtorroot)方法,而不是传递的布局类型,但在attachtorroot为false时,我们得到了该layoutResource的根ViewGroup的函数返回类型。

让我用一个例子来解释:

如果我们有一个线性布局作为根布局,然后我们要添加TextView在它通过膨胀函数。

然后使用attachtorroot作为真正的膨胀函数返回一个LinearLayout类型的视图

而在使用attachtorroot作为虚假膨胀函数时,返回一个类型为TextView的视图

希望这一发现能有所帮助……