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

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

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


当前回答

由于inflation()方法的文档,关于这个主题有很多困惑。

通常,如果attachtorroot被设置为true,那么第一个参数中指定的布局文件将被膨胀,并在那个时刻附加到第二个参数中指定的ViewGroup。当attachtorroot为false时,来自第一个参数的布局文件将膨胀并作为视图返回,任何视图附件都在其他时间发生。

This probably doesn't mean much unless you see a lot of examples. When calling LayoutInflater.inflate() inside of the onCreateView method of a Fragment, you will want to pass in false for attachToRoot because the Activity associated with that Fragment is actually responsible for adding that Fragment's view. If you are manually inflating and adding a View to another View at some later point in time, such as with the addView() method, you will want to pass in false for attachToRoot because the attachment comes at a later point in time.

您可以在我写的一篇关于这个主题的博客文章中阅读其他几个关于对话框和自定义视图的独特示例。

https://www.bignerdranch.com/blog/understanding-androids-layoutinflater-inflate/

其他回答

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

如果设置为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是真还是假的主要区别是这样的。

当你输入attachtorroot

true:立即将子视图添加到父视图 false:现在将子视图添加到父视图。 稍后再添加。`

什么时候?

后面就是使用parent。addview (childView)

一个常见的误解是,如果attachtorroot参数为false,那么子视图将不会被添加到父视图。错误的 在这两种情况下,子视图将被添加到parentView。这只是时间问题。

inflater.inflate(child,parent,false);
parent.addView(child);   

等于

inflater.inflate(child,parent,true);

一个大禁忌 当您不负责将子视图添加到父视图时,永远不要将attachtorroot传递为true。 当添加片段时

public View onCreateView(LayoutInflater inflater,ViewGroup parent,Bundle bundle)
  {
        super.onCreateView(inflater,parent,bundle);
        View view = inflater.inflate(R.layout.image_fragment,parent,false);
        .....
        return view;
  }

如果你传递第三个参数为true,你会得到IllegalStateException,因为这个家伙。

getSupportFragmentManager()
      .beginTransaction()
      .add(parent, childFragment)
      .commit();

因为你已经在onCreateView()中错误地添加了子片段,调用add会告诉你子视图已经添加到父视图,因此IllegalStateException。 这里你不负责添加childView, FragmentManager负责。这里总是传递false。

注意:我还读到,如果attachtorroot为false, parentView将不会获得childView touchEvents。但我还没有测试过。

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

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

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

让我用一个例子来解释:

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

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

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

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

由于inflation()方法的文档,关于这个主题有很多困惑。

通常,如果attachtorroot被设置为true,那么第一个参数中指定的布局文件将被膨胀,并在那个时刻附加到第二个参数中指定的ViewGroup。当attachtorroot为false时,来自第一个参数的布局文件将膨胀并作为视图返回,任何视图附件都在其他时间发生。

This probably doesn't mean much unless you see a lot of examples. When calling LayoutInflater.inflate() inside of the onCreateView method of a Fragment, you will want to pass in false for attachToRoot because the Activity associated with that Fragment is actually responsible for adding that Fragment's view. If you are manually inflating and adding a View to another View at some later point in time, such as with the addView() method, you will want to pass in false for attachToRoot because the attachment comes at a later point in time.

您可以在我写的一篇关于这个主题的博客文章中阅读其他几个关于对话框和自定义视图的独特示例。

https://www.bignerdranch.com/blog/understanding-androids-layoutinflater-inflate/

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

家长:

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

attachToRoot:

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

希望这能澄清困惑